Mongodb - Rückgabe der Punkte, die einem Ort am nächsten liegen, mit Entfernung

7

Was entspricht der MongoDB dieser Abfrage:

SELECT 111151.29341326 * SQRT( pow(-6.186753-`Latitude`, 2) 
                               + pow(106.772835-`Longitude`, 2)
                                 * cos(-6.186753*0.017453292519943)
                                 * cos(`Latitude`*0.017453292519943)
                             )
       as distance
from tablename ;

Dies verwendet die Haversine-Formel , um den Großkreisabstand zu einem festen Punkt zu berechnen. Wir möchten die nächsten 20 Punkte von einem Ort erhalten und dann die Entfernung anzeigen.

user4951
quelle

Antworten:

7

MongoDB hat Unterstützung für Geoindexing eingebaut. Sie müssen die Berechnung nicht selbst durchführen.

Grundsätzlich würden Sie ein Feld erstellen, in dem lat / long als Array oder als Unterdokument gespeichert ist, etwa eines der folgenden:

{ loc : [ 50 , 30 ] } //SUGGESTED OPTION
{ loc : { x : 50 , y : 30 } }
{ loc : { lon : 40.739037, lat: 73.992964 } }

Indizieren Sie dann das neue Loc-Feld entsprechend:

db.places.ensureIndex( { loc : "2d" } )

Schließlich können Sie einen der Operatoren verwenden, um einen Punkt nach den nächsten 20 Ergebnissen abzufragen:

db.places.find( { loc : { $near : [50,50] } } ).limit(20)

Sie könnten natürlich einfach MongoDB verwenden, um die Daten zu speichern, dann die Informationen mit find () aus der Datenbank abrufen und die Berechnung clientseitig durchführen, aber ich stelle mir vor, dass Sie dies nicht tun möchten.

Wenn der Abstandsteil der Gleichung Ihren Wünschen entspricht:

http://www.mongodb.org/display/DOCS/Geospatial+Indexing#GeospatialIndexing-geoNearCommand

Der Operator $ geoNear gibt auch die Entfernung zurück. Ein Beispiel:

> db.runCommand( { geoNear : "places" , near : [50,50], num : 10 } );
{
        "ns" : "test.places",
        "near" : "1100110000001111110000001111110000001111110000001111",
        "results" : [
                {
                        "dis" : 69.29646421910687,
                        "obj" : {
                                "_id" : ObjectId("4b8bd6b93b83c574d8760280"),
                                "y" : [
                                        1,
                                        1
                                ],
                                "category" : "Coffee"
                        }
                },
                {
                        "dis" : 69.29646421910687,
                        "obj" : {
                                "_id" : ObjectId("4b8bd6b03b83c574d876027f"),
                                "y" : [
                                        1,
                                        1
                                ]
                        }
                }
        ],
        "stats" : {
                "time" : 0,
                "btreelocs" : 1,
                "btreelocs" : 1,
                "nscanned" : 2,
                "nscanned" : 2,
                "objectsLoaded" : 2,
                "objectsLoaded" : 2,
                "avgDistance" : 69.29646421910687
        },
        "ok" : 1
}

Die "dis" : 69.29646421910687Elemente sind genau das, wonach Sie suchen. Es gibt auch eine Option für den sphärischen Abstand.

Weitere Informationen zu Geoindexen und deren Verwendung finden Sie hier.

http://www.mongodb.org/display/DOCS/Geospatial+Indexing/

Adam C.
quelle
Das verstehe ich schon. Ich möchte jedoch, dass das Rückgabeergebnis das Feld "Entfernung" enthält. Wie erreicht man das?
user4951
1
Ich glaube nicht, dass Sie die Seite gelesen haben, die ich verlinkt habe - ich habe die Antwort erweitert, um die Operatoren einzuschließen, die die Entfernung zurückgeben, sie sind nur weiter unten auf der Seite
Adam C
Was ist, wenn die zusätzliche Spalte, die wir haben möchten, nicht die Entfernung ist, sondern etwas anderes?
user4951
"etwas anderes" ist zu vage, um zu antworten, wenn Sie eine generische Berechnung wünschen, dann Map / Reduce oder das Aggregation Framework in 2.2
Adam C
In MySQL können Sie dem gewünschten Ergebnis Spalten hinzufügen, normalerweise basierend auf der Formel. Wenn die Tabelle 4 Spalten enthält, können Sie eine Ansicht mit 6 Spalten erhalten. Schaffst du das auf Mongodb? Sieht so aus, als müssten Sie die Daten abrufen und die Spalten selbst berechnen. Ich versuche nur sicher zu gehen.
user4951