Nog beter dan het origineel, je kunt nu $expr
binnen een $match
fase na de initiële $geoNear
:
db.collection.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 23.027573, 72.50675800000001 ],
},
"distanceField": "distance"
}},
{ "$match": { "$expr": { "$lte": [ "$distance", "$radius" ] } }}
])
Eigenlijk een beetje meer optimaal dan toen het voor het eerst werd geschreven. Nu kunnen we gewoon $redact
in plaats van $project
de boolean en $match
later:
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"
}
}}
])
U heeft de informatie precies opgeslagen zoals u zou moeten, maar er is een andere benadering om de resultaten te krijgen dan u denkt.
Wat je wilt gebruiken is een $geoNear
en specifiek het aggregatieraamwerk
vorm van die exploitant. Dit is wat je doet:
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 } }
])
Met die vorm kan de afstand vanaf het opgevraagde punt dus in de resultaten worden "geprojecteerd", terwijl de zoekopdracht ook alleen de dichtstbijzijnde documenten retourneert.
Dan gebruik je een logische vergelijking om te zien of de "afstand"-waarde kleiner is dan "radius", dus binnen de cirkel.
Ten slotte match je om alleen die resultaten te filteren waar die "binnen"-bewering waar was.
U kunt andere opties toevoegen aan $geoNear
zoals weergegeven in de documentatie. Ik zou ook sterk aanbevelen dat je opslag ook het GeoJSON-formaat gebruikt, omdat dat waarschijnlijk beter compatibel is met alle andere bibliotheken die je zou kunnen gebruiken om aan de verkregen resultaten te werken.