Noch optimaler als das Original können Sie jetzt $expr
innerhalb eines $match
Phase nach dem anfänglichen $geoNear
:
db.collection.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 23.027573, 72.50675800000001 ],
},
"distanceField": "distance"
}},
{ "$match": { "$expr": { "$lte": [ "$distance", "$radius" ] } }}
])
Eigentlich etwas optimaler als zu Beginn geschrieben. Jetzt können wir einfach $redact
statt $project
der boolesche Wert und $match
später:
db.collection.aggregate([
// Match documents "near" the queried point
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 23.027573, 72.50675800000001 ],
},
"distanceField": "distance"
}},
// Calculate if distance is within radius and remove if not
{ "$redact": {
"$cond": {
"if": { "$lte": [ "$distance", "$radius" ] },
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
Sie haben die Informationen genau so gespeichert, wie Sie es sollten, aber es gibt einen anderen Ansatz, um die Ergebnisse zu erhalten, als Sie denken.
Was Sie verwenden möchten, ist ein $geoNear
und insbesondere das Aggregations-Framework
Form dieses Operators. So gehen Sie vor:
db.collection.aggregate([
// Match documents "near" the queried point
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 23.027573, 72.50675800000001 ],
},
"distanceField": "distance"
}},
// Calculate if distance is within radius
{ "$project": {
"location": 1,
"radius": 1,
"distance": 1,
"within": { "$lte": [ "$distance", "$radius" ] }
}},
// Match only documents within the radius
{ "$match": { "within": true } }
])
Dieses Formular ermöglicht es also, die Entfernung vom abgefragten Punkt in die Ergebnisse "hochzurechnen", während die Abfrage auch nur die nächstgelegenen Dokumente zurückgibt.
Dann sehen Sie mit einem logischen Vergleich, ob der Wert für "Distanz" kleiner als "Radius" ist, also innerhalb des Kreises.
Schließlich passen Sie an, um nur die Ergebnisse herauszufiltern, bei denen diese "innerhalb"-Behauptung wahr war.
Sie können $geoNear
weitere Optionen hinzufügen wie in der Dokumentation gezeigt. Ich würde auch dringend empfehlen, dass Ihr Speicher auch das GeoJSON-Format verwendet, da dies wahrscheinlich besser mit anderen Bibliotheken kompatibel ist, die Sie möglicherweise verwenden, um an den erzielten Ergebnissen zu arbeiten.