Where $geoNear takes location field in mongodb? - mongodb

I have used $near in match stage of aggregation framework, but in latest versions of mongodb it doesn't work. So I read the documentaion and can't find where to set the location field.
Here it is in near query:
{
<location field>: {
$near: {
$geometry: {
type: "Point" ,
coordinates: [ <longitude> , <latitude> ]
},
$maxDistance: <distance in meters>,
$minDistance: <distance in meters>
}
}
}
And here is the $geoNear query from example:
{
$geoNear: {
near: { type: "Point", coordinates: [ -73.99279 , 40.719296 ] },
distanceField: "dist.calculated",
minDistance: 2,
query: { type: "public" },
includeLocs: "dist.location",
num: 5,
spherical: true
}
}
What if I have two different location fields in one document? Don't understand how it may work.

prerequisite for geoNear:
You should provide a 2dsphere index for the collection
There must be only one 2dsphere index for that collection
Thus, we could conclude that geoNear will only pick the one and only column that is 2dsphere-indexed

Related

mongoDb using $geoNear and $near filter latitude and longitude. Error (Extra field found: $maxDistance: 1000.0)

I have fetched data based on near by 1km radius using latitude and longitude. $near working fine but $geoNear not working getting some error.
Error : MongoServerError: geo near accepts just one argument when querying for a GeoJSON point. Extra field found: $maxDistance: 1000.0
{
$geoNear: {
near: {
type: "Point", coordinates: [ queryData.lat,queryData.long ]
},
distanceField: "dist",
maxDistance: 1000,
key: 'loc',
query: {store:"normal" }
spherical: true
}
}
loc: {
$near : {
$geometry: { type: "Point", coordinates: [ queryData.lat,queryData.long ] },
$maxDistance: 1000
}
},

MongoDB find documents using geo query depending on fields inside document

The following is an example of a MongoDB document:
{
radius: 5000,
location: {
type: 'Point',
coordinates: [60.1241, 12.12454351] // [long, lat]
}
}
Now I want to be able to query/find all documents for which a given point p = [long, lat] falls inside the radius given by the circle with center location.coordinates and radius radius.
The best I came up with is this
find({
"location": {
$geoWithin: {
$centerSphere: [p, 5000],
},
},
});
but I do not know how to get the radius to not be hardcoded but be from the document field.
I found a similar question and created a working solution to my problem from that. (Geospatial $near within current document field value)
You have to add an index of 2dsphere first. (https://docs.mongodb.com/manual/core/2dsphere/)
Then use the following aggregation:
aggregate([
{
$geoNear: {
near: {
type: "Point",
coordinates: [60.1241, 12.12454351],
},
distanceField: "distance",
maxDistance: 40000, // optional (can be set if you know the max radius)
},
},
{
$redact: {
$cond: {
if: { $lte: ["$distance", "$radius"] },
then: "$$KEEP",
else: "$$PRUNE",
},
},
},
]);
You first calculate and add a new field distance. Then you only keep the documents that have a distance lte the radius.

Does geoNear aggregation not work when the query field is the objectId?

My geonear code work except when I put query: {id: req.params.id}. It works for any other filter obj I put.
Does anyone know how to query for a certain document using the objectId while using geoNear?
I presently have what's below. Is there also any way to do the matching on the document first i.e {$match: {id: req.params.id}. I tried doing this but since $geoNear has to be the first step in the pipeline it didn't work out.
const distances = await User.aggregate([
{
$geoNear: {
near: {
type: "Point",
coordinates: [lng, lat],
},
// maxDistance: 13.3333 * 1000,
spherical: true,
distanceField: "distance",
distanceMultiplier: 0.001,
query: { _id: req.params.id },
},
},
{ $project: { id: 1, distance: 1 } },
]);
unable to use $match operator for mongodb/mongoose aggregation with ObjectId ^ This fixed it sorry!

Question for using $geoNear twice in mongodb

I want to make a mongodb query to search companies by applying following filter.
{
myLocation: [lng1, lat1], // That is to get distance from current location to companies on result.
region: [lng2, lat2], //That is to get companies within a radius in this region
radius: 10000,
tags: ["tag1", "tag2"],
sort: "asc" // to sort by nearest from current location.
}
I thought it needs to use $geoNear twice and made an aggregation like this.
{
$geoNear: {
near: {
type: "Point",
coordinates: myLocation
},
distanceField: 'distance1',
maxDistance: radius,
spherical: true,
},
$match: { tags: tags },
$geoNear: {
near: {
type: "Point",
coordinates: region
},
distanceField: 'distance2',
spherical: true,
}
}
but it occurs an error - $geoNear is only valid as the first stage in a pipeline.
Is there any way to make a query to work this filter.
Appreciate your help.

Find $nearSphere result with zero distance from queried point

I have the following record in my mongoDb:
{
"_id" : ObjectId("56e63313059484f212a4305f"),
"title" : "The video title",
"location" : {
"coordinates" : [
-73.9667,
40.78
],
"type" : "Point"
},
}
I want to be able to find all the points at that exact location.
If I write:
db.videos.find({
location: {
'$nearSphere': {
'$geometry': {
type: 'Point',
coordinates: [-73.9667, 40.78]
},
'$maxDistance': 0
}
}
})[0]
I don't get any results. If I type:
db.videos.find({
location: {
'$nearSphere': {
'$geometry': {
type: 'Point',
coordinates: [-73.9667, 40.78]
},
'$maxDistance': 0.00001
}
}
})[0]
I get the one result.
I looked and looked, and nowhere in the docs say that maxDistance cannot be 0.
Can it?
So as would make sense, $maxDistance set to 0 would be ignored just as if you had not set the option.
If you are looking for an "exact match" then just ask for that. It's not a $nearSphere query by any description:
db.videos.find({
"location.coordinates" : [ -73.9667, 40.78 ]
})
Which will of course return the document matching that "exact" location.
For something a little more complex, then use aggregation $geoNear instead. It projects a "distance" which you can use in later filtering:
db.videos.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ -73.9667, 40.78 ]
},
"distanceField": "distance",
"spherical": true
}},
{ "$match": { "distance": 0 } }
])
So the intial pipeline stage returns a "distance" and the second stage filters out any results where that distance was in fact 0.
You really only should need that if your queried objects were something like a "Polygon" or other GeoJSON form that would not match the "exact" coordinates array.
The general "exact" array match should suit for "Point" data.