在存储的圈子中查找位置 [英] Find a Location within a stored Circle

查看:35
本文介绍了在存储的圈子中查找位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have data in MongoDB representing a Circle as follows:

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

我想用lat&查询来确定位置是否与存储的纬度和经度及半径保持一致.

I want to query with lat & long to determine whether the location is withing stored lat&long and radius.

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

I tried following query but unable to execute:

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

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

How can we used stored radius in geoWithin query?

推荐答案

比原始版本更优化,现在您可以使用 $geoNear :

Even more optimal than the original, you can now use $expr within a $match stage after the initial $geoNear:

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


实际上比第一次编写时要更好.现在我们可以 $redact 而不是 $project 布尔值和


Actually a little more optimal than when first written. Now we can just $redact rather than $project the boolean and $match later:

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"
        }
    }}
])


您已经按照实际的方式存储了信息,但是获得结果的方法与您想象的不同.


You've stored the information exactly how you should, but there is a different approach to getting the results than you think.

您要使用的是 $geoNear ,尤其是聚合框架该运算符的形式.这是您的工作:

What you want to use is a $geoNear and specifically the aggregation framework form of that operator. Here's what you do:

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 } }
])

因此该格式允许在结果中投影"到查询点的距离,而查询也将仅返回最近的文档.

So that form allows the distance from the queried point to be "projected" in the results, whilst the query will also only return the nearest documents.

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

Then you use a logical comparison to see if the "distance" value is less than "radius", therefore within the circle.

最后,您进行匹配以仅过滤那些在内"断言为真的结果.

Finally you match to filter out only those results where that "within" assertion was true.

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

You can add other options to $geoNear as shown in the documentation. I would also strongly suggest that your storage should also use the GeoJSON format as that is likely to be more compatible to whatever other libraries you might use to work on the results obtained.

这篇关于在存储的圈子中查找位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆