Е, би било по-хубаво, ако можете да използвате обект GeoJSON, за да представите местоположението, но към момента поддържаните типове всъщност са ограничени така че типът "Кръг", който би бил идеален, не се поддържа.
Най-близкото, което бихте могли да направите, е "Многоъгълник", приближаващ кръг, но това вероятно е твърде много работа за конструиране само за тази цел на заявката. Другото нещо, когато правите това и след това прилагате $geoIntersects
е, че резултатите няма да бъдат "сортирани" по разстоянието от точката на заявката. Това изглежда е обратното на целта да се намери „най-близката пица“ до мястото на произход.
За щастие има $geoNear
операция, добавена към рамката за агрегиране от MongoDB 2.4 и по-нова версия. Хубавото тук е, че позволява "проекция" на поле за разстояние в резултатите. След това това ви позволява да извършите логическото филтриране на сървъра до тези точки, които са „в рамките на ограничението на радиуса“ спрямо разстоянието от точката на произход. Освен това позволява сортиране и на сървъра.
Но все пак ще трябва да промените схемата си, за да поддържате индекса
db.places.insert({
"name": "Pizza Hut",
"location": {
"type": "Point",
"coordinates": [
151.00211262702942,
-33.81696995135973
]
},
"radius": 20
})
db.places.ensureIndex({ "location": "2dsphere" })
И за заявката за агрегиране:
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 } }
])
По принцип това казва,
Има и други опции, които можете да прехвърлите към $geoNear
за да прецизирате резултата, както и да върнете повече от 100 резултата по подразбиране, ако е необходимо, и основно да подадете други опции за заявка, като например „тип“ или „име“ или каквато и да е друга информация, която имате в документа.