MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Finden Sie Punkte in der Nähe von LineString in Mongodb sortiert nach Entfernung

Wie Sie bereits erwähnt haben, unterstützt Mongo derzeit nichts anderes als Point . Sind Sie auf das Konzept eines Routeboxers gestoßen? 1 Es war vor ein paar Jahren sehr beliebt bei Google Maps. Finden Sie anhand der gezeichneten Linie Haltestellen innerhalb von dist(x) . Dazu wurde eine Reihe von Begrenzungsrahmen um jeden Punkt in der Linie erstellt und nach Punkten gesucht, die in den Eimer fallen.

Ich bin über Ihre Frage gestolpert, nachdem ich gerade festgestellt habe, dass Mongo nur mit Punkten arbeitet, was vernünftig ist, nehme ich an.

Ich habe bereits einige Möglichkeiten, wie es geht (sie erweitern das, was @mnemosyn im Kommentar sagt). Bei dem Datensatz, an dem ich arbeite, ist alles clientseitig, also könnte ich den Routeboxer verwenden, aber ich würde ihn aus Leistungsgründen gerne serverseitig implementieren. Hier sind meine Vorschläge:

  1. Unterbrechen Sie den LineString in seine einzelnen Koordinatensätze herunter und frage nach $near Verwenden Sie diese, kombinieren Sie die Ergebnisse und extrahieren Sie einen einzigartigen Satz. Es gibt Algorithmen zur Vereinfachung einer komplexen Linie, indem die Anzahl der Punkte reduziert wird, aber eine einfache ist einfach zu schreiben.

  2. machen Sie dasselbe wie oben, aber als gespeicherte Prozedur/Funktion. Ich habe nicht mit den gespeicherten Funktionen von Mongo herumgespielt, und ich weiß nicht, wie gut sie mit Treibern funktionieren, aber das könnte schneller sein als die erste Option oben, da Sie keine Roundtrips machen müssen, und je nach Maschine das Ihre Instanz(en) von Mongo wird/werden gehostet, Berechnungen könnten um Mikrosekunden schneller sein.

  3. Implementieren Sie den routeboxer-Ansatz serverseitig (wurde in PHP durchgeführt) und verwenden Sie dann einen der beiden oben genannten, um Stopps zu finden, die $within sind die resultierenden Begrenzungsrahmen. Verdammt, da die routeboxer-Methode Rechtecke zurückgibt, wäre es möglich, alle diese Rechtecke zu einem Polygon zusammenzuführen, das Ihre Route abdeckt, und einfach ein $within auszuführen auf diesem. (Was @mnemosyn vorgeschlagen hat).

  4. BEARBEITEN: Ich habe darüber nachgedacht, es aber vergessen, aber es könnte möglich sein, einige der oben genannten Aufgaben mit dem Aggregations-Framework zu erreichen.

Es ist etwas, an dem ich bald arbeiten werde (hoffentlich), ich werde meine Ergebnisse öffentlich zugänglich machen, basierend darauf, was ich am Ende machen werde.

BEARBEITEN: Ich muss jedoch erwähnen, dass 1 und 2 den Fehler haben, dass Sie, wenn Sie 2 Punkte in einer Linie haben, die beispielsweise 2 km voneinander entfernt sind, und Punkte innerhalb von 1,8 km von Ihrer Linie entfernt möchten, offensichtlich alle Punkte zwischen diesem Teil verpassen Ihrer Linie. Die Lösung besteht darin, Punkte in Ihre Linie einzufügen, wenn Sie sie vereinfachen (ich weiß, schlägt das Ziel, Punkte zu reduzieren, wenn Sie neue hinzufügen).

Der Fehler bei 3 ist dann, dass es nicht immer genau ist, da einige Punkte innerhalb Ihres Polygons wahrscheinlich eine Entfernung haben, die größer als Ihr Limit ist, obwohl die Differenz keinen signifikanten Prozentsatz Ihres Limits ausmachen würde.

[1 ] google maps utils routeboxer