【问题标题】:$geoNear matching nearest array$geoNear 匹配最近的数组
【发布时间】:2017-05-31 09:22:07
【问题描述】:

我在记录集合 Mongodb (3.4) 中有文档,如下所示:-

    { 
      "_id" : ObjectId("592d0c78555a7436b0883960"), 
      "userid" : 7, 
       "addresses" : [
        {
            "apporx" : 50.0, 
            "loc" : [
                -73.98137109999999, 
                40.7476039
            ]
        }, 
        {
            "apporx" : 15.0, 
            "loc" : [
                -73.982002, 
                40.74767
            ]          
        }, 
        {
            "apporx" :10.0, 
            "loc" : [
                -73.9819567, 
                40.7471609
            ]
        }
     ]
    }
`

I created index on this collection using below query :- 
`db.records.createIndex({'addresses.loc':1})`

when i execute my below query :-
`db.records.aggregate( 
      {$geoNear : {
        near : [ -73.9815103, 40.7475731 ],
        distanceField: "distance" 
    }});

这个结果给了我距离字段。现在你能在我的文档中解释一下这个多个元素中存在哪个地址数组吗?我怎样才能确定这个结果对于哪个元素是正确的?

另一个问题:- 如果我在“addresses.apporx”上设置条件大于或等于,那么有什么方法可以找到这个条件的位置吗?

【问题讨论】:

    标签: mongodb geolocation mongodb-query aggregation-framework


    【解决方案1】:

    首先,如果您打算对真实世界坐标进行地理空间查询,我强烈建议您为您的收藏创建一个“2dsphere”索引。

    确保删除您可能一直在使用的其他索引:

    db.records.dropIndexes();
    db.records.createIndex({ "addresses.loc": "2dsphere" })
    

    为了做你想做的事,首先看一下还包括$geoNearincludeLocs选项的轻微修改

    db.records.aggregate([
      { "$geoNear": {
         "near": [ -73.9815103, 40.7475731 ],
         "spherical": true,
         "distanceField": "distance",
         "includeLocs": "locs"
      }}
    ])
    

    现在您将看到如下所示的输出:

    {
            "_id" : ObjectId("592d0c78555a7436b0883960"),
            "userid" : 7,
            "addresses" : [
                    {
                            "apporx" : 50,
                            "loc" : [
                                    -73.98137109999999,
                                    40.7476039
                            ]
                    },
                    {
                            "apporx" : 15,
                            "loc" : [
                                    -73.982002,
                                    40.74767
                            ]
                    },
                    {
                            "apporx" : 10,
                            "loc" : [
                                    -73.9819567,
                                    40.7471609
                            ]
                    }
            ],
            "distance" : 0.0000019174641401278624,
            "locs" : [
                    -73.98137109999999,
                    40.7476039
            ]
    }
    

    所以返回的不仅是到最近点的距离,而且是“哪个”位置是使用的匹配项。

    所以如果你想$filter返回最接近的原始数组,那么你可以:

    db.records.aggregate([
      { "$geoNear": {
         "near": [ -73.9815103, 40.7475731 ],
         "spherical": true,
         "distanceField": "distance",
         "includeLocs": "locs"
      }},
      { "$addFields": {
        "addresses": {
          "$filter": {
            "input": "$addresses",
            "as": "address",
            "cond": { "$eq": [ "$$address.loc", "$locs" ] }
          }
        }
      }}
    ])
    

    返回只有匹配项的数组:

    {
            "_id" : ObjectId("592d0c78555a7436b0883960"),
            "userid" : 7,
            "addresses" : [
                    {
                            "apporx" : 50,
                            "loc" : [
                                    -73.98137109999999,
                                    40.7476039
                            ]
                    }
            ],
            "distance" : 0.0000019174641401278624,
            "locs" : [
                    -73.98137109999999,
                    40.7476039
            ]
    }
    

    【讨论】:

    • 谢谢..我的第一个问题已经解决了。但是我的另一个问题是:-如果我在“addresses.apporx”上设置条件大于或等于,那么有没有办法找到这种情况的位置?
    • @SandipKumar 不确定您的意思,这可能是一个不同的问题。但是,如果您的意思是 “与投影到文档中的距离字段比较”,那么就像上面一样,添加另一个管道阶段来比较两个值。为此,请使用$project$redact,并阅读$geoNear 手册页中有关“distanceField”的文档。
    • @SandipKumar 在“距离”这一点上。使用 GeoJSON 表单可能比使用传统的“数组”表单更好。原因是从“遗留”返回的“距离”以 弧度 为单位,需要转换为公里。用于比较时的 GeoJSON 坐标将始终以 为单位返回结果。所以这可能与“存储距离”更加一致。
    • GeoJSON 中有没有像我的“数组”形式一样的方法。我的问题是:- 在这个数组中有多个元素,所以我有一个键,即 "apporx" 。所以首先我想要50到70之间的“大约”这样的条件。这样距离就会计算出元素之间的距离。希望你明白了。
    • @SandipKumar 我真的不确定我是否理解你的意思。如果您的意思是使用“apporx”在 12 到 20 之间设置查询条件,因此仅考虑数组的第二个元素是最近的,那么您不能这样做,并且数组不是最好的存储。如果您的意思是获取最近的结果,然后简单地从结果中“删除”任何没有数组条目或“匹配”数组条目与该范围内的值的文档,那么 yes 你可以这样做.这真的最好在一个单独的问题中提出。
    猜你喜欢
    • 1970-01-01
    • 2014-03-24
    • 1970-01-01
    • 2012-04-17
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-02
    相关资源
    最近更新 更多