sql >> Databáze >  >> NoSQL >> MongoDB

Najděte body poblíž LineString v mongodb seřazené podle vzdálenosti

Jak jste zmínil, Mongo v současné době nepodporuje nic jiného než Point . Setkali jste se s pojmem route boxer? 1 To bylo velmi populární před několika lety na Google Maps. Vzhledem k linii, kterou jste nakreslili, najděte zastávky, které jsou v rámci dist(x) . Bylo to provedeno vytvořením řady ohraničujících rámečků kolem každého bodu v linii a hledáním bodů, které spadají do kbelíku.

Narazil jsem na vaši otázku poté, co jsem si právě uvědomil, že Mongo pracuje pouze s body, což je podle mě rozumné.

Už mám pár možností, jak to udělat (rozšiřují to, co říká @mnemosyn v komentáři). S datovou sadou, na které pracuji, je vše na straně klienta, takže bych mohl použít router, ale chtěl bych ho implementovat na straně serveru z důvodu výkonu. Zde jsou mé návrhy:

  1. přerušte LineString dolů do jednotlivých sad souřadnic a dotazem na $near pomocí každého z nich zkombinujte výsledky a extrahujte jedinečnou sadu. Existují algoritmy pro zjednodušení složitého řádku snížením počtu bodů, ale jednoduchý se snadno píše.

  2. proveďte totéž jako výše, ale jako uloženou proceduru/funkci. Nehrál jsem si s uloženými funkcemi Mongo a nevím, jak dobře fungují s ovladači, ale mohlo by to být rychlejší než první možnost výše, protože nebudete muset dělat zpáteční cesty a v závislosti na počítači to vaše instance Mongo je(jsou) hostována, výpočty mohou být rychlejší o mikrosekundy.

  3. Implementujte přístup routeboxer na straně serveru (byl proveden v PHP) a poté použijte některou z výše uvedených 2 k nalezení zastávek, které jsou $within výsledné ohraničující rámečky. Sakra, protože metoda routeboxer vrací obdélníky, bylo by možné sloučit všechny tyto obdélníky do jednoho polygonu pokrývajícího vaši trasu a prostě udělat $within na tom. (Co navrhl @mnemosyn).

  4. UPRAVIT: Myslel jsem na to, ale zapomněl jsem na to, ale některé z výše uvedených možností by bylo možné dosáhnout pomocí agregačního rámce.

Je to něco, na čem budu brzy (doufejme) pracovat, poskytnu open source své výsledky, na základě kterých nakonec použiji.

UPRAVIT: Musím však zmínit, že 1 a 2 mají tu chybu, že pokud máte 2 body v linii, které jsou od sebe řekněme 2 km, a chcete body, které jsou do 1,8 km od vaší čáry, zjevně vám uniknou všechny body mezi touto částí. vaší linie. Řešením je vložit body do vaší čáry při jejím zjednodušení (vím, překonává cíl zmenšit body při přidávání nových zpět).

Chyba 3 pak spočívá v tom, že to nebude vždy přesné, protože některé body ve vašem mnohoúhelníku budou mít pravděpodobně vzdálenost větší, než je váš limit, i když rozdíl by nepředstavoval významné procento vašeho limitu.

[1 ] Mapy google využívají routeboxer



  1. MongoDB seznam dostupných databází v Javě

  2. Uložte obrázek v MongoDB pomocí Node.js/Express a Mongoose

  3. Použití _id generovaných MongoDB jako tajných dat (např. tokenů OAuth)

  4. Dotaz pokrytý MongoDB není schopen uspokojit dotaz z Indexu