【问题标题】:Find a Location within a stored Circle在存储的圈子中查找位置
【发布时间】:2015-03-22 03:26:48
【问题描述】:

我在 MongoDB 中有一个表示圆的数据,如下所示:

{
    "_id" : ObjectId("54c1dc6506a4344d697f7675"),
    "location" : [ 
        23.027573, 
        72.50675800000001
    ],
    "radius" : 500
}

我想用 lat & long 查询以确定该位置是否包含存储的 lat&long 和半径。

我尝试了以下查询但无法执行:

db.test.find({location:{ $geoWithin: { $center: [ [ -74, 40.74 ] ,
                                                         "$radius"] } }})

我们如何在 geoWithin 查询中使用存储的半径?

【问题讨论】:

  • 感谢@Neil Lunn 编辑

标签: mongodb geolocation geospatial mongodb-query aggregation-framework


【解决方案1】:

甚至比原来更优化,您现在可以在初始 $geoNear 之后的 $match 阶段内使用 $expr

db.collection.aggregate([
    { "$geoNear": {
        "near": {
            "type": "Point",
            "coordinates": [ 23.027573, 72.50675800000001 ],
        },
        "distanceField": "distance"
    }},
    { "$match": { "$expr": { "$lte": [ "$distance", "$radius" ] } }}
])

实际上比第一次编写时更优化。现在我们可以只使用 $redact 而不是 $project 布尔值和稍后的 $match

db.collection.aggregate([
    // Match documents "near" the queried point
    { "$geoNear": {
        "near": {
            "type": "Point",
            "coordinates": [ 23.027573, 72.50675800000001 ],
        },
        "distanceField": "distance"
    }},

    // Calculate if distance is within radius and remove if not
    { "$redact": {
        "$cond": {
            "if": { "$lte": [ "$distance", "$radius" ] },
            "then": "$$KEEP",
            "else": "$$PRUNE"
        }
    }}
])

您已按照应有的方式准确存储信息,但获取结果的方法与您想象的不同。

您要使用的是$geoNear,特别是该运算符的aggregation framework 形式。这是你要做的:

db.collection.aggregate([
    // Match documents "near" the queried point
    { "$geoNear": {
        "near": {
            "type": "Point",
            "coordinates": [ 23.027573, 72.50675800000001 ],
        },
        "distanceField": "distance"
    }},

    // Calculate if distance is within radius
    { "$project": {
        "location": 1,
        "radius": 1,
        "distance": 1,
        "within": { "$lte": [ "$distance", "$radius" ] }
    }},

    // Match only documents within the radius
    { "$match": { "within": true } }
])

因此,该表单允许在结果中“投影”到查询点的距离,而查询也只会返回最近的文档。

然后您使用逻辑比较来查看“距离”值是否小于“半径”,因此在圆内。

最后,您匹配以仅过滤掉那些“内部”断言为真的结果。

您可以向$geoNear 添加其他选项,如文档中所示。我还强烈建议您的存储也应使用 GeoJSON 格式,因为这可能与您可能用于处理获得的结果的任何其他库更兼容。

【讨论】:

    【解决方案2】:

    MongoDB 为基于 GEO 的查询提供强大的支持。要检查您的位置是否在您提到的中心内,有一个$geoNear

    【讨论】:

      猜你喜欢
      • 2016-11-18
      • 1970-01-01
      • 2013-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多