1
db.units.aggregate([
  {
    "$geoNear": {
      "near": {
        "type": "Point",
        "coordinates": [ -3.70256, 40.4165 ]
      },
      "distanceField": "dist.calculated",
      "spherical": true,
      "maxDistance": 50000
    }
  },
  {
    $match: {
      "some.field.a": true,
      "otherField": null
    }
  }
]).explain("executionStats");

Gives me:

nReturned: 671,
          executionTimeMillis: 8,
          totalKeysExamined: 770,
          totalDocsExamined: 671,

However:

db.units.aggregate([
  {
    "$geoNear": {
      "near": {
        "type": "Point",
        "coordinates": [ -3.70256, 40.4165 ]
      },
      "distanceField": "dist.calculated",
      "spherical": true,
      "maxDistance": 50000,
      "query": {
        "some.field.a": true,
        "otherField": null
      }
    }
  }
]).explain("executionStats");

Gives me:

 nReturned: 67,
          executionTimeMillis: 6,
          totalKeysExamined: 770,
          totalDocsExamined: 1342,

The first question which comes to my mind is, why the number of returned documents is different? The second one is, why the totalDocsExamined is higher when using query of $geoNear?

Updated When query field of $geoNear is used, there is a COLLSCAN to find all documents matching the query filter. Unless you create a compound index with all fields: db.units.createIndex({coordinates:'2dsphere', 'some.field.': 1, otherField:1 )

So it seems like the behavior in case of using query is by default a COLLSCAN except if you have a compounded index with the geospatial field plus the ones included in query.

Ignasi
  • 5,887
  • 7
  • 45
  • 81
  • What version of mongodb is this where `db.units.aggregate([...]).explain()` is valid? `explain()` is a function for a `find()` cursor. To get stats from an agg pipeline you have to use `db.units.aggregate([...], {explain:true})` – Buzz Moschetti May 19 '22 at 12:29
  • Using MongoDB: 4.4.6 Using Mongosh: 1.2.3 – Ignasi May 19 '22 at 13:33

1 Answers1

0

Reason is that query param of geoNear decides the number of docs examined.

Limits the results to the documents that match the query. The query syntax is the usual MongoDB read operation query syntax.

In your first case, it's considered as pipeline. geoNear executes first then match stage. Hence the number changes.

Gibbs
  • 21,904
  • 13
  • 74
  • 138
  • This would explain why the number of docs examined is different...however, the number of docs returned by the query {"some.field.a": true, "otherField": null} is around 100. So why the second case is examining *more* docs? – Ignasi May 19 '22 at 11:35
  • And about the number of returned documents, I still don't understand why are different, could you be more specific? Thanks! – Ignasi May 19 '22 at 11:36
  • Did you execute the query individually and calculated the matching docs? – Gibbs May 20 '22 at 05:09