如何为 mongo 数据库模式定义一个圆圈?

How to define a circle for a mongo db schema?

我有以下代码来定义模式:

var mongoose=require('mongoose');
var Schema=mongoose.Schema;
var PostSchema=new Schema({
location:{type:Array,required:false,select:true}
})
PostSchema.index({location:'2dsphere'});

module.exports=mongoose.model('Post',PostSchema);

我想让位置字段看起来像一个圆圈(例如:位置:{loc:[latitude,longitude],radius:radius})..我想查询从我的数据库中找到圆圈与 polygon.Thanks 相交以获得任何帮助:)

要对 "geospatial query" 有效,"location" 必须按 经度、纬度 顺序并且不能包含任何其他坐标。

有效格式为

 { 
     "location": [long,lat]
 }

 {
    "location": { "lng": long, "lat": lat }
 }

或 GeoJSON

 {
     "location": {
         "type": "Point",
         "coordinates": [long,lat]
     }
 }

另一个字段如"radius"是"another field"并且不能是同一个数组的一部分。

最好遵循 GeoJSON:

 {
     "location": {
         "type": "Point",
         "coordinates": [long,lat]
     },
     "radius": radius
 }

在 mongoose 模式定义中可以像这样简单:

var geoSchema = new Schema({
    "location": {
        "type": String,
        "coordinates": []
    },
    "radius": Number
});

在真实 "globe" 坐标处处理地理空间数据时,您的索引应为 "2dsphere",您可以选择在架构中将其定义为:

geoSchema.index({ "location": "2dsphere" })

由于在受支持的 GeoJSON 中没有对 "Circle" 对象的实际支持,因此建议将另一个字段保留为 "radius" 并存储 "center point"。

GeoJSON 相对于其他 "legacy coordinate pairs" 格式的 "big" 优势在于,当通过 geoNear or $geoNear 从某个点返回类似 "distance" 的内容时, "distance" 在 "meters" 中一致定义。这也是您在存储中定义任何 "radius" 值以与该结果保持一致的方式。

如果使用其他存储格式,结果将返回 "radians",您可能希望对其进行转换,但不希望将 "radius" 的圆作为测量值存储.

你处理这个问题的方法是,考虑这种形式的数据:

{
    "locationtype": "circle",
    "location": {
        "type": "Point",
        "coordinates": [1,1]
    },
    "radius": 4
}

然后你用.aggregate() with a $geoNear stage and a $redact过滤:

db.collection.aggregate([
    // Find points or objects "near" and project the distance
    { "$geoNear": {
        "near": {
            "type": "Point",
            "coordinates": [2,2]
        },
        "distanceField": "distance",
        "query": { "locationType": "circle" }
    }},
    // Logically filter anything outside of the radius
    { "$redact": {
        "$cond": {
            "if": { "$gt": [ "$distance", "$radius" ] },
            "then": "$$PRUNE",
            "else": "$$KEEP"
        }
    }}
])

现在查询示例中使用的值只是一个示例,但如 "real" 经纬度坐标所述,"distance" 属性按设计运行并在 "meters" 范围内公差如前所述。

这里的要点是,无论对象类型是什么,$geoNear 都会找到 "near" 到 "circle" 中心点。不仅如此,此处的命令还在文档中生成另一个字段的 "projection",如 "distanceField" 中所命名。这表示与 "meters".

中圆 "center" 的距离

此处的第二阶段使用 $redact,因为它有点像 $project and $match pipeline stage in one. Unlike $match this operator can evaluate a "logical" condition by comparing fields present in the document. In this case, operations like $$PRUNE remove the matched document to the "if" condition where true and "remove" it from results or otherwise $$KEEP 条件为 false.

的文档

在"nutshell"中,如果"distance"是"greater than"那么"circle"的"radius"那么圆的对象"lies outside"和没有 "intersect"。否则 "it does".


这就是 "defining a 'circle' for geometry in a collection and " 使用它的基础知识”,以实现 "Point" 或 "circle" 半径内其他类型对象之间的交集。