Конвейер агрегации MongoDB $geoNear (с использованием параметра запроса и с использованием операции конвейера $match), выдающий разные результаты

Я использую $geoNear в качестве первого шага в структуре агрегации. Мне нужно отфильтровать результаты на основе поля "тег", и он работает нормально, но я вижу, что есть два способа, которые дают разные результаты.

Образец документа MongoDB

    {
      "позиция": [
        40,80143,
        -73,96095
      ],
      "тег": "пицца"
    }

Я добавил 2dsphere индекс к ключу "позиция"

    db.restaurants.createIndex( { 'position': "2dsphere" })

Запрос 1

использует операцию конвейера агрегации $match для фильтрации результатов по ключу "tag"
    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

Использует запрос внутри операции агрегации $geoNear для фильтрации результатов по ключу "тег"
    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
                    ]
                  }
                }
              }},


        ])
Другие вопросы по тегам