通过 geoNear 获取子文档 - MongoDB

Posted

技术标签:

【中文标题】通过 geoNear 获取子文档 - MongoDB【英文标题】:Gets sub documents by geoNear - MongoDB 【发布时间】:2015-03-17 04:43:13 【问题描述】:

我有这种情况。

在我们的数据库中有“商店”文档和“分公司”作为子文档(一对多)。

每个分支机构都有一个位置属性,为地理位置搜索编制索引。

所以,问题是:

store:"name":"store1", branchoffices:["name":"bo1","location":[ -70.64341379999999, -33.4268697 ], "name":"bo2","location":[80.4,43.3]]

如果我做这个聚合:

Store.collection.aggregate(
        [
            "$geoNear"=>"near"=>[ -70.64341379999999, -33.4268697 ], 
            "distanceField"=>"distance", 
            "maxDistance"=>0.0900899926955034
        ,
         "$unwind" => "$branchoffices"
    ]

返回的结果是每个分支机构的距离字段在两行或记录中重复。刚在 geoNear 找到一个分支机构时。

是否存在某种方式只返回地理定位搜索结果的子文档或子文档?

谢谢。

【问题讨论】:

【参考方案1】:

$geoNear下的选项为includeLocs,如下:

Store.aggregate([
     "$geoNear": 
        "near": [ -70.64341379999999, -33.4268697 ],
        "distanceField": "distance", 
        "maxDistance": 0.0900899926955034,
        "includeLocs": "location"
    
])

输出具有与输出字段中的“距离”匹配的“位置”:


    "_id" : ObjectId("5507b18d1c3bdce0535aecd0"),
    "name" : "store1",
    "branchoffices" : [
            
                    "name" : "bo1",
                    "location" : [
                            -70.64341379999999,
                            -33.4268697
                    ]
            ,
            
                    "name" : "bo2",
                    "location" : [
                            80.4,
                            43.3
                    ]
            
    ],
    "distance" : 0,
    "location" : [
            -70.64341379999999,
            -33.4268697
    ]

如果您想详细了解匹配中使用的数组中的特定子文档,那么您可以使用$redact 继续过滤:

Store.aggregate([
     "$geoNear": 
        "near": [ -70.64341379999999, -33.4268697 ],
        "distanceField": "distance", 
        "maxDistance": 0.0900899926955034,
        "includeLocs": "location"
    ,
     "$redact": 
        "$cond": [
             "$eq": [ "$location", "$$ROOT.location" ] ,
            "$$DESCEND",
            "$$PRUNE"
        ]
    
])

或者在 MongoDB 2.6 之前的版本中,如下所示:

Store.aggregate([
     "$geoNear": 
        "near": [ -70.64341379999999, -33.4268697 ],
        "distanceField": "distance", 
        "maxDistance": 0.0900899926955034,
        "includeLocs": "location"
    ,
     "$unwind": "$branchoffices" ,
     "$project": 
        "name": 1,
        "branchoffices": 1,
        "matched": 
            "$eq": [ "$location", "$branchoffices.location" ]
        
    ,
     "$match":  "matched": 1  ,
     "$group": 
        "_id": "$_id",
        "name":  "$first": "$name" ,
        "branchoffices":  "$push": "$branchoffices" ,
        "distance":  "$first" "$distance" 
    
])

您可能应该注意到,在子文档中使用对象并不总是最佳解决方案,而且通常不适合各种任务。例如,如果数组中的数据可能包含“靠近”查询点的“多个”位置,则只有单个“最近”点能够像这样匹配。

因此,尽管您可以做到这一点,但最好考虑您如何使用它以及您期望的结果。在大多数情况下,位置数据应该列在它自己的文档中,而不是像这里所做的那样在子文档数组下。

【讨论】:

感谢尼尔的回答。最后,我的问题的解决方案是将商店和分支机构分开,以使所有分支机构靠近一个坐标。我希望未来的 MongoDB 支持这种类型的查询,虽然比这种方式操作更有意义和逻辑。问候。

以上是关于通过 geoNear 获取子文档 - MongoDB的主要内容,如果未能解决你的问题,请参考以下文章

将 $geoNear 与另一个集合组合

获取数组中每个索引的子文档元素计数并更新子文档键 - 数组中的子文档(IN MONGODB)

GraphQL和MongoDB` $ geoNear`聚合

如何对嵌入式文档进行 $geoNear 聚合?

将 geoNear 查询与另一个查询组合以获取值

java mongodb“geoNear”命令返回异常错误17304