I have data in MongoDB representing a Circle as follows:
{
"_id" : ObjectId("54c1dc6506a4344d697f7675"),
"location" : [
23.027573,
72.50675800000001
],
"radius" : 500
}
I want to query with lat & long to determine whether the location is withing stored lat&long and radius.
I tried following query but unable to execute:
db.test.find({location:{ $geoWithin: { $center: [ [ -74, 40.74 ] ,
"$radius"] } }})
How can we used stored radius in geoWithin query?
Even more optimal than the original, you can now use $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" ] } }}
])
Actually a little more optimal than when first written. Now we can just $redact
rather than $project
the boolean and $match
later:
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"
}
}}
])
You've stored the information exactly how you should, but there is a different approach to getting the results than you think.
What you want to use is a $geoNear
and specifically the aggregation framework form of that operator. Here's what you do:
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 } }
])
So that form allows the distance from the queried point to be "projected" in the results, whilst the query will also only return the nearest documents.
Then you use a logical comparison to see if the "distance" value is less than "radius", therefore within the circle.
Finally you match to filter out only those results where that "within" assertion was true.
You can add other options to $geoNear
as shown in the documentation. I would also strongly suggest that your storage should also use the GeoJSON format as that is likely to be more compatible to whatever other libraries you might use to work on the results obtained.
MongoDB provides strong support for GEO based query. To check whether your location is within the centre you mentioned, there is a $geoNear.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With