Ancora più ottimale dell'originale, ora puoi utilizzare $expr
all'interno di un $match
fase dopo il $geoNear
:
db.collection.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 23.027573, 72.50675800000001 ],
},
"distanceField": "distance"
}},
{ "$match": { "$expr": { "$lte": [ "$distance", "$radius" ] } }}
])
In realtà un po' più ottimale di quando è stato scritto per la prima volta. Ora possiamo solo $redact
anziché $project
il booleano e $match
dopo:
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"
}
}}
])
Hai memorizzato le informazioni esattamente come dovresti, ma c'è un approccio diverso per ottenere i risultati da quello che pensi.
Quello che vuoi usare è un $geoNear
e in particolare il framework di aggregazione
forma di tale operatore. Ecco cosa fai:
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 } }
])
Quindi quel modulo consente di "proiettare" nei risultati la distanza dal punto interrogato, mentre la query restituirà anche solo i documenti più vicini.
Quindi usi un confronto logico per vedere se il valore di "distanza" è inferiore a "raggio", quindi all'interno del cerchio.
Infine, abbini per filtrare solo i risultati in cui l'asserzione "dentro" era vera.
Puoi aggiungere altre opzioni a $geoNear
come mostrato nella documentazione. Suggerirei inoltre caldamente che il tuo spazio di archiviazione utilizzi anche il formato GeoJSON in quanto è probabile che sia più compatibile con qualsiasi altra libreria tu possa utilizzare per lavorare sui risultati ottenuti.