Jeszcze bardziej optymalny niż oryginał, możesz teraz użyć $expr
w ramach $match
etap po początkowym $geoNear
:
db.collection.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 23.027573, 72.50675800000001 ],
},
"distanceField": "distance"
}},
{ "$match": { "$expr": { "$lte": [ "$distance", "$radius" ] } }}
])
Właściwie trochę bardziej optymalna niż przy pierwszym napisaniu. Teraz możemy po prostu $redact
zamiast $project
wartość logiczna i $match
później:
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"
}
}}
])
Informacje zostały zapisane dokładnie tak, jak powinny, ale istnieje inne podejście do uzyskiwania wyników niż myślisz.
To, czego chcesz użyć, to $geoNear
a konkretnie struktura agregacji
formy tego operatora. Oto, co robisz:
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 } }
])
Tak więc ta forma pozwala na "odwzorowanie" odległości od badanego punktu w wynikach, podczas gdy zapytanie zwróci tylko najbliższe dokumenty.
Następnie używasz logicznego porównania, aby sprawdzić, czy wartość „odległość” jest mniejsza niż „promień”, a więc w obrębie okręgu.
Na koniec dopasowujesz, aby odfiltrować tylko te wyniki, w których stwierdzenie „wewnątrz” było prawdziwe.
Możesz dodać inne opcje do $geoNear
jak pokazano w dokumentacji. Gorąco sugerowałbym również, aby twoje przechowywanie również używało formatu GeoJSON, ponieważ prawdopodobnie będzie on bardziej kompatybilny z innymi bibliotekami, których możesz użyć do pracy z uzyskanymi wynikami.