Sunday, August 19, 2018

Will using $near with $maxDistance and $and act as a filter in MongoDB?

Leave a Comment

So if we run a GeoSpatial MongdoDB query with a maxDistance like this:

db.getCollection('Places').aggregate([{   "$geoNear": {     "near": {       "type": "Point",       "coordinates": [-0.1251485, 51.5174914]     },     "spherical": true,     "distanceField": "dist",     "maxDistance": 2000,     "query": {       "field": "xxx"     }   } } }]) 

we get the following results as an Example:

[PlaceA, PlaceB, PlaceC]

Then, let's say we run the following query:

db.getCollection('Places').aggregate([{     "$geoNear": {       "near": {         "type": "Point",         "coordinates": [-0.1251485, 51.5174914]       },       "spherical": true,       "distanceField": "dist",       "maxDistance": 2000,       "query": {         "field": "xxx"       }     }   },   {     $and: {       name: {         $eq: 'PlaceA'       }     },   } ]) 

Assuming that we are trying to get PlaceA in this query.

Correct if I am wrong, but doesn't MongoDB apply the geo query first and selects PlaceA, PlaceB, PlaceC and then filters out PlaceB and PlaceC. In other words, the $and is just acting as a filter and we can do the same filtering with a for loop rather than putting it in the MongoDB query:

for (eachPlace in Places) {    if (eachPlace == 'PlaceA') {      return eachPlace;    } } 

2 Answers

Answers 1

First of all, I think you're referring to the $match operation, not $and, as $and cannot standalone in the pipeline.

Second, Documents pass through the stages in sequence. so your thought is correct, the aggregation pipeline just applies filter on documents passed the previous stage

Third, in some aggregation, you see that the order of computation is not as same as order of pipeline. It's because MongoDB is smart enough to optimize the pipeline, it can merge stages, reorder stages... for maximum performance.

For more detail you can look at the optimization here

Answers 2

You can put all the filters inside query, No need for another pipeline

db.getCollection('Places').aggregate([{     "$geoNear": {       "near": {         "type": "Point",         "coordinates": [-0.1251485, 51.5174914]       },       "spherical": true,       "distanceField": "dist",       "maxDistance": 2000,       "query": {         "field": "xxx",         "name": {"$eq": 'PlaceA'}       }     }   } ]) 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment