我有以下代码来定义架构:
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:[纬度,经度],半径:半径})..我想查询从我的数据库中找到圆圈与多边形相交。感谢任何帮助:)
答案 0 :(得分:4)
要对"geospatial query"有效,“位置”必须为经度,纬度顺序且不能包含任何其他坐标。
有效格式为
{
"location": [long,lat]
}
或
{
"location": { "lng": long, "lat": lat }
}
或GeoJSON
{
"location": {
"type": "Point",
"coordinates": [long,lat]
}
}
另一个字段如“radius”是“另一个字段”而不能是同一个数组的一部分。
理想情况下遵循GeoJSON:
{
"location": {
"type": "Point",
"coordinates": [long,lat]
},
"radius": radius
}
在mongoose模式定义中可以如下这样简单:
var geoSchema = new Schema({
"location": {
"type": String,
"coordinates": []
},
"radius": Number
});
在真实“地球”坐标处理地理空间数据时,您的索引应为"2dsphere",您可以选择在架构上定义为:
geoSchema.index({ "location": "2dsphere" })
由于在支持的GeoJSON中没有对“Circle”对象的实际支持,因此建议将另一个字段保留为“radius”并存储“中心点”。
GeoJSON相对于其他“遗留坐标对”格式的“巨大”优势在于,当通过geoNear
或$geoNear
从点返回“距离”之类的东西时,那么“距离”是始终以“米”定义。这也是您应该如何定义存储中的任何“半径”值以保持与该结果一致。
使用其他存储格式,结果将以“弧度”返回,您可能希望转换该结果,并且不希望存储圆的“半径”,并将其作为度量。
处理这个问题的方法是,考虑这种形式的数据:
{
"locationtype": "circle",
"location": {
"type": "Point",
"coordinates": [1,1]
},
"radius": 4
}
然后您使用.aggregate()
$geoNear
阶段和$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"
}
}}
])
现在查询示例中使用的值只是一个示例,但正如“真实”经度和纬度坐标所述,“距离”属性按设计工作,并且在前面提到的“米”公差范围内。
这里的要点是$geoNear
无论对象类型是什么,都会在“圆圈”中心找到“附近”。不仅如此,而且这里的命令正在生成文档中另一个字段的“投影”,如“distanceField”中所述。这表示与“米”中的圆“中心”的距离。
此处的第二阶段使用$redact
,因为它有点像$project
和$match
管道阶段。与$match
不同,此运算符可以通过比较文档中存在的字段来评估“逻辑”条件。在这种情况下,$$PRUNE
之类的操作会将匹配的文档移除到“if”条件,其中true
并从结果中“删除”它,或者$$KEEP
条件为{{1}的文档}}
在“简言之”中,如果“距离”是“大于”,那么“圆圈”的“半径”则物体“位于圆圈外”并且不“相交”。否则“它确实”。
这就是“为集合中的几何定义'圆''和”使用它“来实现类似”圆“半径内”点“或其他类型对象之间交点的基础。