Cóż, byłoby lepiej, gdybyś mógł użyć obiektu GeoJSON do reprezentowania lokalizacji, ale od teraz obsługiwane typy są faktycznie ograniczone więc idealny typ „Okrąg” nie jest obsługiwany.
Najbliższe, co możesz zrobić, to „Wielokąt” aproksymujący okrąg, ale jest to prawdopodobnie trochę za dużo pracy do skonstruowania tylko dla tego celu zapytania. Drugi problem z wykonaniem tego, a następnie zastosowaniem $geoIntersects
jest to, że wyniki nie będą „posortowane” według odległości od punktu zapytania. Wydaje się to być przeciwieństwem celu znalezienia „najbliższej pizzy” do miejsca pochodzenia.
Na szczęście istnieje $geoNear
operacja dodana do struktury agregacji od MongoDB 2.4 i nowszych. Dobrą rzeczą jest to, że pozwala na "odwzorowanie" pola odległości w wynikach. Pozwala to następnie na wykonanie logicznego filtrowania na serwerze do tych punktów, które znajdują się w ograniczeniu „w promieniu” do odległości od punktu początkowego. Umożliwia również sortowanie na serwerze.
Ale nadal będziesz musiał zmienić swój schemat, aby obsługiwał indeks
db.places.insert({
"name": "Pizza Hut",
"location": {
"type": "Point",
"coordinates": [
151.00211262702942,
-33.81696995135973
]
},
"radius": 20
})
db.places.ensureIndex({ "location": "2dsphere" })
A dla zapytania agregującego:
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 } }
])
Zasadniczo mówi to:
Istnieją inne opcje, które możesz przekazać do $geoNear
w celu doprecyzowania wyniku, a także zwrócenia więcej niż domyślnych 100 wyników, jeśli jest to wymagane, i zasadniczo przekazania innych opcji do zapytania, takich jak „typ” lub „nazwa” lub jakiekolwiek inne informacje, które masz w dokumencie.