在存储的圆圈内查找位置
Find a Location within a stored Circle
我在 MongoDB 中有代表圆的数据如下:
{
"_id" : ObjectId("54c1dc6506a4344d697f7675"),
"location" : [
23.027573,
72.50675800000001
],
"radius" : 500
}
我想查询纬度和经度以确定该位置是否包含存储的纬度和经度和半径。
我尝试了以下查询但无法执行:
db.test.find({location:{ $geoWithin: { $center: [ [ -74, 40.74 ] ,
"$radius"] } }})
我们如何在 geoWithin 查询中使用存储的半径?
比原来的更优化,你现在可以使用$expr
within a $match
stage after the initial $geoNear
:
db.collection.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 23.027573, 72.50675800000001 ],
},
"distanceField": "distance"
}},
{ "$match": { "$expr": { "$lte": [ "$distance", "$radius" ] } }}
])
实际上比第一次写的时候优化了一点。现在我们可以稍后 $redact
rather than $project
the boolean and $match
:
db.collection.aggregate([
// Match documents "near" the queried point
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 23.027573, 72.50675800000001 ],
},
"distanceField": "distance"
}},
// Calculate if distance is within radius and remove if not
{ "$redact": {
"$cond": {
"if": { "$lte": [ "$distance", "$radius" ] },
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
您已经按照应有的方式存储了信息,但是获取结果的方法与您想象的不同。
您要使用的是该运算符的 $geoNear
and specifically the aggregation framework 形式。这是您的操作:
db.collection.aggregate([
// Match documents "near" the queried point
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 23.027573, 72.50675800000001 ],
},
"distanceField": "distance"
}},
// Calculate if distance is within radius
{ "$project": {
"location": 1,
"radius": 1,
"distance": 1,
"within": { "$lte": [ "$distance", "$radius" ] }
}},
// Match only documents within the radius
{ "$match": { "within": true } }
])
因此该表格允许结果中距查询点的距离为"projected",同时查询也将仅return最近的文档。
然后你用逻辑比较,看"distance"值是否小于"radius",所以在圆内。
最后,您匹配以仅过滤掉那些 "within" 断言为真的结果。
您可以向 $geoNear
添加其他选项,如文档中所示。我还强烈建议您的存储也应该使用 GeoJSON 格式,因为它可能与您可能用来处理获得的结果的任何其他库更兼容。
MongoDB 对基于 GEO 的查询提供了强大的支持。要检查您的位置是否在您提到的中心内,有一个 $geoNear.
我在 MongoDB 中有代表圆的数据如下:
{
"_id" : ObjectId("54c1dc6506a4344d697f7675"),
"location" : [
23.027573,
72.50675800000001
],
"radius" : 500
}
我想查询纬度和经度以确定该位置是否包含存储的纬度和经度和半径。
我尝试了以下查询但无法执行:
db.test.find({location:{ $geoWithin: { $center: [ [ -74, 40.74 ] ,
"$radius"] } }})
我们如何在 geoWithin 查询中使用存储的半径?
比原来的更优化,你现在可以使用$expr
within a $match
stage after the initial $geoNear
:
db.collection.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 23.027573, 72.50675800000001 ],
},
"distanceField": "distance"
}},
{ "$match": { "$expr": { "$lte": [ "$distance", "$radius" ] } }}
])
实际上比第一次写的时候优化了一点。现在我们可以稍后 $redact
rather than $project
the boolean and $match
:
db.collection.aggregate([
// Match documents "near" the queried point
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 23.027573, 72.50675800000001 ],
},
"distanceField": "distance"
}},
// Calculate if distance is within radius and remove if not
{ "$redact": {
"$cond": {
"if": { "$lte": [ "$distance", "$radius" ] },
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
您已经按照应有的方式存储了信息,但是获取结果的方法与您想象的不同。
您要使用的是该运算符的 $geoNear
and specifically the aggregation framework 形式。这是您的操作:
db.collection.aggregate([
// Match documents "near" the queried point
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 23.027573, 72.50675800000001 ],
},
"distanceField": "distance"
}},
// Calculate if distance is within radius
{ "$project": {
"location": 1,
"radius": 1,
"distance": 1,
"within": { "$lte": [ "$distance", "$radius" ] }
}},
// Match only documents within the radius
{ "$match": { "within": true } }
])
因此该表格允许结果中距查询点的距离为"projected",同时查询也将仅return最近的文档。
然后你用逻辑比较,看"distance"值是否小于"radius",所以在圆内。
最后,您匹配以仅过滤掉那些 "within" 断言为真的结果。
您可以向 $geoNear
添加其他选项,如文档中所示。我还强烈建议您的存储也应该使用 GeoJSON 格式,因为它可能与您可能用来处理获得的结果的任何其他库更兼容。
MongoDB 对基于 GEO 的查询提供了强大的支持。要检查您的位置是否在您提到的中心内,有一个 $geoNear.