我在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”上设置条件,例如大于或等于,那么有什么方法可以找到该条件的位置吗?

#1 楼

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

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

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


为了做您想做的事,首先请看一下在$geoNear中包含includeLocs选项

 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”上设置条件,例如大于或等于,那么有什么方法可以找到此条件的位置吗?

– 5a01d01P
17年5月31日在10:37

@SandipKumar不确定您的意思,那可能是另一个问题。但是,如果要表示投影到文档中的“与distanceField进行比较”,则与上面类似,请添加另一个管道阶段以比较这两个值。为此,请使用$ project和$ redact,然后从$ geoNear手册页上阅读“ distanceField”上的文档。

–尼尔·伦(Neil Lunn)
17年5月31日在10:44

@SandipKumar关于“距离”。使用GeoJSON表单可能比使用传统的“数组”表单更好。原因是“传统”返回的“距离”以弧度表示,需要转换为公里。在比较中使用GeoJSON坐标时,将始终以米为单位返回结果。因此,这可能与“存储的距离”更加一致。

–尼尔·伦(Neil Lunn)
17年5月31日上午10:47

有什么办法可以像我的“数组”形式那样在GeoJSON中使用。我的问题是:-在此数组中有多个元素,因此我有一个键,即“ apporx”。所以首先我要条件在50到70之间,例如“大约”,这样距离将在elements.hope之间计算。

– 5a01d01P
17年5月31日晚上10:53

@SandipKumar我真的不确定我是否理解您的意思。如果您要执行类似的操作,例如使用“ apporx”在12到20之间设置查询条件,以便仅考虑数组的第二个元素,那么您就不能这样做,数组也不是最佳的存储方式。如果要获取最接近的结果,然后简单地从没有数组条目或“匹配”数组条目的值在该范围内的结果中“删除”任何文档,那么可以。确实最好在一个单独的问题中提出。

–尼尔·伦(Neil Lunn)
17年5月31日在11:09