Ännu mer optimal än originalet kan du nu använda $expr
inom en $match
skede efter den initiala $geoNear
:
db.collection.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 23.027573, 72.50675800000001 ],
},
"distanceField": "distance"
}},
{ "$match": { "$expr": { "$lte": [ "$distance", "$radius" ] } }}
])
Egentligen lite mer optimalt än när det först skrevs. Nu kan vi bara $redact
snarare än $project
boolean och $match
senare:
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"
}
}}
])
Du har lagrat informationen precis som du ska, men det finns ett annat sätt att få resultaten än du tror.
Det du vill använda är en $geoNear
och specifikt aggregationsramverket
operatörens form. Så här gör du:
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 } }
])
Så det formuläret tillåter att avståndet från den frågade punkten "projiceras" i resultaten, medan frågan också bara returnerar de närmaste dokumenten.
Sedan använder du en logisk jämförelse för att se om "distans"-värdet är mindre än "radie", alltså inom cirkeln.
Slutligen matchar du för att filtrera bort endast de resultat där det "inom" påståendet var sant.
Du kan lägga till andra alternativ till $geoNear
som visas i dokumentationen. Jag skulle också starkt föreslå att din lagring också bör använda GeoJSON-formatet eftersom det sannolikt är mer kompatibelt med alla andra bibliotek du kan använda för att arbeta med de erhållna resultaten.