Reputation: 7853
I'm trying to achieve the following behaviour with a mongodb query:
location
and a 2dshere geospatial index on that fieldmaxdistance
user.gps
as a GeoJSON pointThe query currently looks like this:
query["location"] = {
$nearSphere: {
$geometry: user.gps,
$maxDistance: filterDistance
}
};
This query successfully selects all the datasets in a given filterDistance
relative to the user.
What i'd like to have now is "If document.maxdistance
field > 0 and the distance to the user is greater than document.maxdistance
" do not select the dataset.
So i have documents that should not be found if the user lives in a distance greater than a given distance saved inside the document.
I don't know hot to express this in a mongodb query and i couldn't find any example of such a query.
Upvotes: 0
Views: 161
Reputation: 37048
$near/$nearSphere don't support per-document distance. Only per query. The main reason is sorting by distance. If you need only filtering you can use $geoIntersects/$geoWithin, but you will need to change documents to contain a polygon of the covered area, like a circle Pi*2*distance
around it's location.
Example:
Assuming you have a document:
{
loc: { type: "Point", coordinates: [ 10, 20 ] },
distance: 10
}
So that it is returned when user's coordinate is within the radius, e.g. [12, 25]
, and is not returned when user's coordinate is outside, e.g. [12,30]
.
For that documents should be updated to convert loc/distance
pair to a polygon. For the sake of simplicity I'll use octagon, but you may want to increase number of vertices for more accurate results:
{
loc: { type: "Point", coordinates: [ 10, 20 ] },
distance: 10,
area: {
type : "Polygon",
coordinates : [[
[ 17, 27 ],
[ 10, 30 ],
[ 3, 27 ],
[ 0, 20 ],
[ 3, 13 ],
[ 10, 10 ],
[ 17, 13 ],
[ 20, 20 ],
[ 17, 27 ]
]]
}
}
Then you can use $geoIntersects to find documents which area includes user's coordinates:
db.collection.find({
area: {
$geoIntersects: {
$geometry: { type: "Point" , coordinates: [ 12, 25] }
}
}
})
Upvotes: 1