使用查询选项和$match管道操作的MongoDB $geoNear聚合管道返回不同数量的结果

9
我在聚合框架中使用了$geoNear作为第一步骤。我需要基于“tag”字段过滤结果,它可以工作得很好,但我发现有两种方式都能够给出不同的结果。
MongoDB示例文档:
{ "position": [ 40.80143, -73.96095 ], "tag": "pizza" }
我已经将2dsphere索引添加到“position”键。
db.restaurants.createIndex( { 'position' : "2dsphere" } )
查询1:使用$match操作筛选出基于“tag”键的结果
db.restaurants.aggregate( [ { "$geoNear":{ "near": { type: "Point", coordinates: [ 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聚合操作内使用查询来基于“tag”键过滤结果
db.restaurants.aggregate( [ { "$geoNear":{ "query" : {"tag":"pizza"}, "near": { type: "Point", coordinates: [ 55.8284,-4.207] }, "limit":100, "maxDistance":10*1000, "distanceField": "dist.calculated", "includeLocs": "dist.location", "distanceMultiplier":1/1000, "spherical": true } }, { "$group":{"_id":null,"totalDocs":{"$sum":1}} } ] );
这里的分组选项只是为了获取两个查询返回的文档计数。
两个查询返回的totalDocs似乎不同。有人能解释一下这两个查询之间的差异吗?
2个回答

9

几个假设:-
1. 假设有300条记录与位置匹配。
2. 假设前100个结果没有标记为"pizza"。后面的200个文档(101至300)带有"pizza"标签。

查询1:-

  • 有两个流水线操作$geoNear和$match。
  • $geoNear管道操作的输出是$match管道操作的输入。
  • $geoNear根据距离从近到远排序,基于位置找到最多100个结果(我们指定的限制)。 (注意这里返回的100个结果纯粹是基于位置的。因此,这100个结果不包含任何带有"pizza"标签的文档)
  • 这100个结果将被发送到下一个流水线操作$match,过滤发生在这里。但是由于前100个结果没有标记为"pizza",所以输出为空

查询2:-

  • 只有一个流水线操作$geoNear。
  • 在$geoNear管道操作中包括一个查询字段。
  • $geoNear根据距离从近到远排序,基于位置和查询tag=pizza找到最多100个结果(我们指定的限制)。
  • 现在,由于查询已经包括在管道操作$geoNear中,所以输出结果是101到200的文档。简单地说,查找所有带有位置[x,y]和标记为"pizza"的文档。

附言:- $group管道阶段仅用于获取计数,因此在解释中没有写到它。


3
// If you have to apply multiple criteria 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
                    ]
                  }
                }
              }},
        

        ])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接