sql >> Database teknologi >  >> NoSQL >> MongoDB

Find punkter i nærheden af ​​LineString i mongodb sorteret efter afstand

Som du nævnte, understøtter Mongo i øjeblikket ikke andet end Point . Er du stødt på konceptet med en rutebokser? 1 Det var meget populært for nogle år tilbage på Google Maps. I betragtning af den linje, du har tegnet, skal du finde stop, der er inden for dist(x) . Det blev gjort ved at oprette en række afgrænsningsfelter omkring hvert punkt i linjen og søge efter punkter, der falder inden for spanden.

Jeg faldt over dit spørgsmål, efter at jeg lige indså, at Mongo kun arbejder med point, hvilket er rimeligt, går jeg ud fra.

Jeg har allerede et par muligheder for, hvordan man gør det (de udvider, hvad @mnemosyn siger i kommentaren). Med det datasæt, som jeg arbejder på, er det hele på klientsiden, så jeg kunne bruge routeboxeren, men jeg vil gerne implementere den på serversiden af ​​præstationsmæssige årsager. Her er mine forslag:

  1. bryd LineString ned i dets individuelle koordinatsæt, og forespørg efter $near ved at bruge hver af dem, kombiner resultater og udtræk et unikt sæt. Der er algoritmer derude til at forenkle en kompleks linje ved at reducere antallet af punkter, men en enkel er nem at skrive.

  2. gør det samme som ovenfor, men som en lagret procedure/funktion. Jeg har ikke leget med Mongos lagrede funktioner, og jeg ved ikke, hvor godt de fungerer med drivere, men dette kan være hurtigere end den første mulighed ovenfor, da du ikke behøver at køre rundt, og afhængigt af maskinen, din forekomst(er) af Mongo er hostet, beregninger kunne være hurtigere med mikrosekunder.

  3. Implementer routeboxer-tilgangen på serversiden (er blevet udført i PHP), og brug derefter en af ​​de 2 ovenstående til at finde stop, der er $within de resulterende afgrænsningskasser. For pokker, da routeboxer-metoden returnerer rektangler, ville det være muligt at flette alle disse rektangler til én polygon, der dækker din rute, og bare lave en $within på det. (Hvad @mnemosyn foreslog).

  4. EDIT: Jeg tænkte på dette, men glemte det, men det er måske muligt at opnå noget af ovenstående ved hjælp af aggregeringsrammen.

Det er noget, som jeg snart skal arbejde på (forhåbentlig), jeg vil open source mine resultater baseret på, som jeg ender med at gå med.

EDIT: Jeg må dog nævne, at 1 og 2 har den fejl, at hvis du har 2 punkter i en linje, der er f.eks. 2 km fra hinanden, og du vil have punkter, der er inden for 1,8 km fra din linje, vil du naturligvis gå glip af alle punkter mellem den del af din linje. Løsningen er at injicere point på din linje, når du forenkler den (jeg ved, det overgår målet om at reducere point, når du tilføjer nye igen).

Fejlen med 3 er, at den ikke altid vil være nøjagtig, da nogle punkter inden for din polygon sandsynligvis har en afstand, der er større end din grænse, selvom forskellen ikke ville være en væsentlig procentdel af din grænse.

[1 ] google maps utils routeboxer



  1. Alternativer til indlejrede strukturer i Redis?

  2. ActionCable på AWS:Fejl under WebSocket-håndtryk:Uventet svarkode:404

  3. Lukkes en forbindelse til MongoDB automatisk på process.exit()?

  4. uploader fil til mappe på node-express-websted ved hjælp af multer med mongodb