Bene, sarebbe più bello se potessi usare un oggetto GeoJSON per rappresentare la posizione, ma al momento il i tipi supportati sono in realtà limitati quindi un tipo "Cerchio" che sarebbe l'ideale non è supportato.
Il più vicino che potresti fare è un "poligono" che approssima un cerchio, ma questo è probabilmente un po' troppo lavoro da costruire solo per questo scopo di query. L'altra cosa è fare questo e poi applicare $geoIntersects
è che i risultati non verranno "ordinati" in base alla distanza dal punto di query. Questo sembra essere l'opposto dello scopo di trovare la "pizza più vicina" al punto di origine.
Fortunatamente esiste un $geoNear
operazione aggiunta al framework di aggregazione a partire da MongoDB 2.4 e versioni successive. La cosa buona qui è che permette la "proiezione" di un campo di distanza nei risultati. Ciò consente quindi di eseguire il filtraggio logico sul server in quei punti che sono vincolati "entro il raggio" alla distanza dal punto di origine. Consente inoltre l'ordinamento anche sul server.
Ma dovrai comunque cambiare lo schema per supportare l'indice
db.places.insert({
"name": "Pizza Hut",
"location": {
"type": "Point",
"coordinates": [
151.00211262702942,
-33.81696995135973
]
},
"radius": 20
})
db.places.ensureIndex({ "location": "2dsphere" })
E per la query di aggregazione:
db.places.aggregate([
// Query and project distance
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [
150.92094898223877,
-33.77654333272719
]
},
"distanceField": "distance",
"distanceMultiplier": 0.001,
"maxDistance": 100000,
"spherical": true
}},
// Calculate if distance is within delivery sphere
{ "$project": {
"name": 1,
"location": 1,
"radius": 1,
"distance": 1,
"within": { "$gt": [ "$radius", "$distance" ] }
}},
// Filter any false results
{ "$match": { "within": true } },
// Sort by shortest distance from origin
{ "$sort": { "distance": -1 } }
])
Fondamentalmente questo dice,
Ci sono altre opzioni che puoi passare a $geoNear
per perfezionare il risultato, oltre a restituire più dei 100 risultati predefiniti se necessario e sostanzialmente passare altre opzioni da interrogare come un "tipo" o un "nome" o qualsiasi altra informazione che hai sul documento.