$geoNear(聚合管道)未返回正确的文档

5

使用聚合管道中的$geoNear时,返回的结果不正确。但是,使用典型的find()查询(使用$near)可以返回正确的结果。

但是,当移除等式条件(在schedule.key上),两个查询都可以返回正确的数据。

使用聚合管道中的$geoNear

db.place.aggregate(
[
    { 
        $geoNear: { 
            spherical: true,
            near: { type: "Point", coordinates: [ 18.416145, -33.911973 ] },
            distanceField: "dist"
        }
    },
    { 
        $match: { 
            "schedule.key": { "$eq": "vo4lRN_Az0uwOkgBzOERyw" } 
        } 
    }
])

$near查询语句:

db.place.find(
    { 
        "point" : { 
            $near: { 
                type: "Point", 
                coordinates: [ 18.416145,-33.911973 ] 
            } 
        }, 
        "schedule.key" : { 
            $eq : "vo4lRN_Az0uwOkgBzOERyw" 
        }
    })

这个集合中的文档大致长这样:
{
    "_id" : UUID("da6ccbb1-3c7a-45d7-bc36-a5e6007cd919"),
    "schedule" : {
        "_id" : UUID("587de5b7-a744-4b28-baa8-e6efb5f7f921"),
        "key" : "vo4lRN_Az0uwOkgBzOERyw"
    },
    "point" : {
        "type" : "Point",
        "coordinates" : [ 
            18.425102, 
            -33.922153
        ]
    },
    "name" : "Cape Town"
}

我已经在点字段上创建了适当的索引:

db.place.ensureIndex( { "point" : "2dsphere" } );
1个回答

3
这并不是完全相同的查询。使用独立的$match阶段存在明显区别,因为“过滤”仅在“最接近的结果”被找到后才进行。这意味着您可能会返回“较少”的结果,因为标准未组合发出。
这就是为什么$geoNear中有一个"query"选项的原因:
db.place.aggregate(
[
    { 
        $geoNear: { 
            spherical: true,
            near: { type: "Point", coordinates: [ 18.416145, -33.911973 ] },
            distanceField: "dist",
            query: {
                "schedule.key": { "$eq": "vo4lRN_Az0uwOkgBzOERyw" } 
            }
        }
    }
])

现在这是同样的查询。如果你使用$nearSphere,它将完全相同。因为$near在距离计算中不考虑地球曲率。$nearSphere$geoNear会考虑到。

但主要问题是与"query"选项结合使用,因为这是唯一真正同时考虑两个条件的初始搜索的方法。


我没有意识到geoNear阶段实际上有返回文档的限制 - 谢谢。 - Dave New
@davenewza,问题不仅在于“限制”,而且在于“两个”阶段不能像你最初认为的那样合并为单个查询。实际上,在“某些”情况下,聚合管道处理确实会将阶段“合并”在一起,这是我个人的抱怨。个人认为不应该这样做,因为几乎每种情况都会养成糟糕的编程习惯,你真的应该意识到单个阶段的使用。但在给定标准方面,这是一个“苹果和橙子”的特定案例。 - Neil Lunn

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