查找包含点的 Mongodb 地理空间圆

Find Mongoid geospacial circles that contain a point

我有代表本地商家提供的服务的 Mongoid 文档。每个都有一个或多个位置(lat/lng 点)和一个服务区(半径)。给定客户位置(lat/lng 点),如何找到客户位置在服务区域内的所有文档?

class Service
  include Mongoid::Document

  # Data currently stored like this:
  field :address, type: String
  field :service_distance, type: Float

  # Happy to geocdoe and store in another format
end    

大多数示例基于搜索圆内的点(其中半径是查询的一部分并且对所有文档都相同)而不是寻找与点相交的圆(其中圆具有不同的半径)。

通过指定 "centre" 和 "radius" 对 "circle" 进行建模是一种有效的方法,但是查找 "within the circle" 的东西通常很简单,即使不是很明显:

Service.collection.aggregate([

    # Get the distance from the current location
    { "$geoNear" => {
        "near" => {
           "type" => "Point",
           "coordinates" => [ 1, 1 ] 
        },
        "distanceField" => "dist"
    }},

    # Find out if the "dist" is within the radius
    { "$project" => {
        "address" => 1,
        "service_distance" =>1,
        "location" => 1,  # the field with the co-ordinates you add
        "dist" => 1,
        "within" => { "$lt" => [ "$dist", "$service_distance" ] }
    }},

    # Then filter out anything not "within"
    { "$match" => { "within" => true } }

])

因此 $geoNear aggregation 运算符不仅在指定点找到文档 "near",而且还在文档中 "projects" 表示从该点开始的 "distance" 的字段查询。

请注意,您在此处要求的 "extra field" ( "location" ) 是 "Point" 的实际 "co-ordinates" 圆心,其中 "shop" 位于。这是此处所需的附加字段。

接下来要做的就是"compare"计算文档中包含的"radius"或"service_distance"的距离,看看是"less than"还是[=46] =]那个距离。

然后,如果结果是 true,您可以保留这些文件并在您的最终回复中出示它们。

此处的 .collection 访问器允许您使用本机 MongoDB 方法,例如 .aggregate(),它允许进行此类操作。

这就是您在服务器处理中的处理方式。