如何为mongo db模式定义一个圆? [英] 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);
我想使位置字段看起来像一个圆(例如:location:{loc:[latitude,longitude],radius:radius}).与多边形相交.感谢您的帮助:)
要对地理空间查询" 有效,位置"必须按经度,纬度的顺序进行,并且不能包含任何其他坐标.
有效格式为
{
"location": [long,lat]
}
或
{
"location": { "lng": long, "lat": lat }
}
或GeoJSON
{
"location": {
"type": "Point",
"coordinates": [long,lat]
}
}
另一个字段(例如半径")是另一个字段",并且不能成为同一数组的一部分.
理想地遵循GeoJSON:
{
"location": {
"type": "Point",
"coordinates": [long,lat]
},
"radius": radius
}
猫鼬模式定义中的内容可以很简单:
var geoSchema = new Schema({
"location": {
"type": String,
"coordinates": []
},
"radius": Number
});
在真实的地球"坐标处处理地理空间数据时,您的索引应为"2dsphere" ,您可以选择在架构上将其定义为:
geoSchema.index({ "location": "2dsphere" })
由于受支持的GeoJSON中没有对圆"对象的实际支持,因此建议将另一个字段保留为半径"并存储中心点".
与其他传统坐标对"格式相比,GeoJSON的大"优势在于,通过 $geoNear
,则始终以米"为单位定义距离".这也是您应该在存储中定义任何半径"值以保持与该结果一致的方式.
对于其他存储格式,结果以弧度"返回,您可能要对其进行转换,并且不希望将圆的半径"作为度量来存储.
您处理此问题的方法是,以这种形式考虑数据:
{
"locationtype": "circle",
"location": {
"type": "Point",
"coordinates": [1,1]
},
"radius": 4
}
然后,将 .aggregate()
与<一个href ="http://docs.mongodb.org/manual/reference/operator/aggregation/geoNear/" rel ="nofollow"> $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"命名的文档中生成另一个字段的投影".这表示距圆中心"的距离(以米"为单位).
这里的第二阶段使用 这就是定义集合中的几何图形的圆"并使用它"以实现圆"半径内的点"或其他类型的对象之间的交集的基本知识." > I have the folowing code to define a schema: I want to make location field to be seen like a circle(ex:location:{loc:[latitude,longitude],radius:radius})..I want to make a query to find circles form my db which are intersecting with a polygon.Thanks for any help :) To be valid for a "geospatial query" the "location" must be in longitude, latitude order and cannot contain any other coordinates. Valid formats are Or Or GeoJSON Another field such as "radius" is "another field" and cannot be part of the same array. Ideally follow GeoJSON: Which in mongoose schema definition can be as simple as: When dealing with geospatial data at real "globe" coordinates your index should be "2dsphere", which you optionally define on the schema as : Since there is no actual support for a "Circle" object in supported GeoJSON then keeping another field as "radius" and storing the "center point" is recommended. The "big" advantage with GeoJSON over the other "legacy coordinate pairs" formats is that when returning something like a "distance" from a point via With the other storage formats then the result is returned in "radians", for which you probably want to convert and would prefer not to be storing a "radius" of a circle with that as a measurement. The way you deal with this is, considering data in this form: Then you use Now the values used in the query example are just an example, but as stated with "real" longitude and latitude coordinates the "distance" attributes work out as designed and within the "meters" tolerance as mentioned earlier. The points here are that The second stage here uses In a "nutshell", if "distance" is "greater than" then "radius" of the "circle" then the object "lies outside" of the circle and does not "intersect". Otherwise "it does". So that is the basics of "defining a 'circle' for geometry in a collection and "using it" to achieve something like the intersection between a "Point" or other type of Object within the "circle" radius. 这篇关于如何为mongo db模式定义一个圆?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!$redact
,因为它有点像 $project
和 $match
流水线阶段合而为一.与$match
不同,此运算符可以通过比较文档中存在的字段来评估逻辑"条件.在这种情况下, $$PRUNE
将匹配的文档删除为"if"条件,其中true
并将其从结果中删除",否则
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);
{
"location": [long,lat]
}
{
"location": { "lng": long, "lat": lat }
}
{
"location": {
"type": "Point",
"coordinates": [long,lat]
}
}
{
"location": {
"type": "Point",
"coordinates": [long,lat]
},
"radius": radius
}
var geoSchema = new Schema({
"location": {
"type": String,
"coordinates": []
},
"radius": Number
});
geoSchema.index({ "location": "2dsphere" })
geoNear
or $geoNear
then that "distance" is defined in "meters" consistently. This is also how you should be defining any "radius" value in your storage to remain consistent with that result.{
"locationtype": "circle",
"location": {
"type": "Point",
"coordinates": [1,1]
},
"radius": 4
}
.aggregate()
with a $geoNear
stage and a $redact
to filter: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
will both find "near" to the "circle" center poiny no matter what the object type. Not only that but the command here is producing a "projection" of another field in the document here as named in "distanceField". This represents the distance from the circle "center" in "meters".$redact
since it is sort of like a $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
the document where the condition was false
.