【问题标题】:MongoDB print distance between two pointsMongoDB打印两点之间的距离
【发布时间】:2016-02-25 04:05:59
【问题描述】:

当我在 MongoDB 上触发此查询时,我将 500 英里附近的所有地点都获取到指定坐标。但我想知道指定坐标和结果位置之间的确切距离。

db.new_stores.find({ "geometry": { $nearSphere: { $geometry: { type: "Point", coordinates: [ -81.093699, 32.074673 ] }, $maxDistance: 500 * 3963 } } } ).pretty()

我的输出如下:

{
    "_id" : ObjectId("565172058bc200b0db0f75b1"),
    "type" : "Feature",
    "geometry" : {
        "type" : "Point",
        "coordinates" : [
            -80.148826,
            25.941116
        ]
    },
    "properties" : {
        "Name" : "Anthony's Coal Fired Pizza",
        "Address" : "17901 Biscayne Blvd, Aventura, FL"
    }
}

我也想知道这个地方到指定坐标的距离。我在几何上创建了 2dsphere 索引。

【问题讨论】:

    标签: mongodb mongodb-query geospatial


    【解决方案1】:

    您可以使用$geoNear 聚合管道阶段来产生与查询点的距离:

     db.new_stores.aggregate([
        { "$geoNear": {
            "near": {
                "type": "Point",
                "coordinates": [ -81.093699, 32.074673 ]
            }, 
            "maxDistance": 500 * 1609,
            "spherical": true,
            "distanceField": "distance",
            "distanceMultiplier": 0.000621371
        }}
    ]).pretty()
    

    这允许您指定"distanceField",它将在输出文档中生成另一个字段,其中包含与查询点的距离。您还可以使用"distanceMultiplier" 根据需要将任何转换应用于输出距离(即米到英里,并注意所有 GeoJSON 距离都以米为单位返回)

    还有geoNear 命令具有类似的选项,但它当然不会返回游标作为输出。

    【讨论】:

    • 非常感谢,它运行良好。很想知道你为什么将它乘以 1609?
    • @SiMemon 因为一英里有 1609 米,反之亦然。您使用的 3963 数字是“弧度”到英里的转换,与 GeoJSON 点坐标一起使用时会不正确。弧度仅用于存储和查询都使用“旧坐标对”。
    • 我们可以在同一个查询中找到从查询点到多个地理点的距离而不是一个吗?
    • 这可以确定两个圆是否相交吗?也就是说,假设我有一个包含纬度和经度以及半径的集合。由于 GeoJSON 不支持圆,我可以编写一个查询来确定两点之间的距离,然后检查该距离是否小于两个半径的总和?那会起作用吗?它会高效吗?谢谢。
    【解决方案2】:

    MongoDB 提供了一个 $geoNear 聚合器,用于使用 GeoJson 坐标计算集合中文档的距离。

    让我们通过一个简单的例子来理解它。 考虑一个简单的收藏店

    1.创建收藏夹

    db.createCollection('shops')
    

    2.在商店集合中插入文档

    db.shops.insert({name:"Galaxy store",address:{type:"Point",coordinates:[28.442894,77.341299]}})
    
    db.shops.insert({name:"A2Z store",address:{type:"Point",coordinates:[28.412894,77.311299]}})
    
    db.shops.insert({name:"Mica store",address:{type:"Point",coordinates:[28.422894,77.342299]}})
    
    db.shops.insert({name:"Full Stack developer",address:{type:"Point",coordinates:[28.433894,77.334299]}})
    

    3.在“地址”字段上创建 GeoIndex

    db.shops.createIndex({address: "2dsphere" } )
    

    4.现在使用 $geoNear 聚合器 找出有距离的文件。

    db.shops.aggregate([{$geoNear:{near:{type:"Point",coordinates:[28.411134,77.331801]},distanceField: "shopDistance",$maxDistance:150000,spherical: true}}]).pretty()
    

    这里 coordinates:[28.411134,77.331801] 是中心位置或获取文档的位置。

    distanceField:"shopDistance" , $geoNear Aggregator 在结果中返回 shopDistance 作为字段。

    结果:

    { "_id" : ObjectId("5ef047a4715e6ae00d0893ca"), "name" : "Full Stack developer", "address" : { "type" : "Point", "coordinates" : [ 28.433894, 77.334299 ] }, "shopDistance" : 621.2848190449148 }
    { "_id" : ObjectId("5ef0479e715e6ae00d0893c9"), "name" : "Mica store", "address" : { "type" : "Point", "coordinates" : [ 28.422894, 77.342299 ] }, "shopDistance" : 1203.3456146763526 }
    { "_id" : ObjectId("5ef0478a715e6ae00d0893c7"), "name" : "Galaxy store", "address" : { "type" : "Point", "coordinates" : [ 28.442894, 77.341299 ] }, "shopDistance" : 1310.9612119555288 }
    { "_id" : ObjectId("5ef04792715e6ae00d0893c8"), "name" : "A2Z store", "address" : { "type" : "Point", "coordinates" : [ 28.412894, 77.311299 ] }, "shopDistance" : 2282.6640175038788 }
    

    这里 shopDistance 将以米为单位。

    【讨论】:

      【解决方案3】:

      maxDistance -> 可选。文档可以到的中心点的最大距离。 MongoDB 将结果限制在距离中心点指定距离内的那些文档。

      如果指定点是 GeoJSON,则以米为单位指定距离;如果指定点是旧坐标对,则以弧度为单位。

      在文档中,如果您使用 legacy pairs ,例如:near : [long , lat] ,则在 radians 中指定 maxDistance。 如果您使用 GeoJSON ,例如:near : { type : "Point" ,坐标:[long ,lat] }, 然后以 为单位指定 maxDistance。

      【讨论】:

        猜你喜欢
        • 2019-01-23
        • 2012-07-17
        • 1970-01-01
        • 1970-01-01
        • 2019-09-16
        • 2010-10-30
        相关资源
        最近更新 更多