Конвейер агрегации MongoDB $geoNear (с использованием параметра запроса и с использованием операции конвейера $match), выдающий разные результаты
Я использую $geoNear в качестве первого шага в структуре агрегации. Мне нужно отфильтровать результаты на основе поля "тег", и он работает нормально, но я вижу, что есть два способа, которые дают разные результаты.
Образец документа MongoDB
{ "позиция": [ 40,80143, -73,96095 ], "тег": "пицца" }
Я добавил 2dsphere индекс к ключу "позиция"
db.restaurants.createIndex( { 'position': "2dsphere" })
Запрос 1
db.restaurants.aggregate( [ { "$geoNear":{ "near": { type: "Point", координаты: [ 55.8284,-4.207] }, "limit":100, "maxDistance":10*1000, "distanceField": "dist.calculated", "includeLocs": "dist.location", "distanceMultiplier":1/1000, "spherical": true } },{ "$match":{"tag":"pizza"} }, { "$group":{"_id":null,"totalDocs":{"$sum":1}} } ]);
Запрос 2
db.restaurants.aggregate ([ { "$ GeoNear":{ "query": {"tag":"pizza"} "рядом": {тип: "Точка", координаты: [55.8284, -4.207]}, "Предел": 100, "MaxDistance": 10 * 1000, "distanceField": "dist.calculated", "includeLocs": "dist.location", "DistanceMultiplier": 1/1000, "сферический": правда } }, { "$ Группа": { "_ ID": нулевой, "totalDocs": { "$ сумма": 1}} } ]);
Опция группировки - просто получить количество документов, возвращаемых обоими запросами.
TotalDocs, возвращаемые обоими запросами, кажутся разными.
Может ли кто-нибудь объяснить мне разницу между обоими запросами?
2 ответа
Несколько предположений: -
1. Предположим, что есть 300 записей, которые соответствуют в зависимости от местоположения.
2. Предположим, что первый набор из 100 результатов не имеет тега пиццы. Остальные 200 документов (от 101 до 300) имеют тег пиццы
Запрос 1:-
- Есть 2 конвейерных операции $geoNear и $match
- Выходные данные конвейерной операции $geoNear являются входными данными для конвейерной операции $match
- $geoNear находит максимум 100 результатов (указанный нами предел) в зависимости от местоположения, отсортированного по расстоянию от ближайшего к дальнему. (Обратите внимание, что 100 полученных результатов основаны исключительно на местоположении. Таким образом, эти 100 результатов не содержат никакого документа с тегом "пицца")
- Эти 100 результатов отправляются в следующую конвейерную операцию $match, откуда происходит фильтрация. Но так как первый набор из 100 результатов не имел тега pizza, вывод пуст
Запрос 2:-
- Есть только 1 конвейерная операция $geoNear
- Поле запроса, включенное в операцию конвейера $geoNear, $geoNear находит не более 100 результатов (указанное нами ограничение) на основе местоположения, отсортированного по расстоянию от ближайшего к дальнему, и тега запроса =pizza
- Теперь здесь результаты от 101 до 200 возвращаются как выходные данные, так как запрос включен в конвейерную операцию $geoNear. Итак, в простом предложении мы говорим: найдите все документы с местоположением [x,y] с тегом = пицца.
PS: - Этап конвейера $group добавлен только для того, чтобы получить количество и, следовательно, не написал об этом в объяснении.
if you have to apply multiple creteria to find locations then this query might helpful
const userLocations = await userModel.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [data.lon1,data.lat1]
},//set the univercity points
spherical: true,
distanceField: "calcDistance",
// maxDistance: 2400,//25km
"distanceMultiplier": 0.001,
}
},
{ $unwind: "$location" },
{ $match: {
"location": {
$geoWithin: {
$centerSphere: [
[ 73.780553, 18.503327], 20/ 6378.1 //check the user point is present here
]
}
}
}},
])