Bylo by hezčí, kdybyste mohli k reprezentaci umístění použít objekt GeoJSON, ale od současnosti podporované typy jsou ve skutečnosti omezené takže typ "Kruh", který by byl ideální, není podporován.
Nejbližší, co byste mohli udělat, je "polygon" aproximující kružnici, ale to je pravděpodobně příliš mnoho práce na vytvoření pouze pro tento účel dotazu. Druhý dostal s tím, že to uděláte a poté použijete $geoIntersects
je, že výsledky nebudou „řazeny“ podle vzdálenosti od bodu dotazu. To se zdá být opakem účelu najít "nejbližší pizzu" k místu původu.
Naštěstí existuje $geoNear
operace přidána do agregačního rámce od MongoDB 2.4 a vyšší. Dobrá věc je, že umožňuje "projekci" pole vzdálenosti ve výsledcích. To vám pak umožňuje provádět logické filtrování na serveru k těm bodům, které jsou "v okruhu" omezení vzdálenosti od výchozího bodu. Umožňuje také řazení na serveru.
Stále však budete muset změnit své schéma, aby podporovalo index
db.places.insert({
"name": "Pizza Hut",
"location": {
"type": "Point",
"coordinates": [
151.00211262702942,
-33.81696995135973
]
},
"radius": 20
})
db.places.ensureIndex({ "location": "2dsphere" })
A pro agregační dotaz:
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 } }
])
V podstatě to říká,
Existují další možnosti, které můžete předat $geoNear
za účelem upřesnění výsledku a také vrácení více než výchozích 100 výsledků v případě potřeby a v podstatě předání dalších možností dotazu, jako je „typ“ nebo „název“ nebo jakékoli jiné informace, které v dokumentu máte.