如何为 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" 半径内其他类型对象之间的交集。
我有以下代码来定义模式:
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".
此处的第二阶段使用 $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" 半径内其他类型对象之间的交集。