Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-23065

Geo predicate beneath $elemMatch object causes planner to ignore valid index with 2dsphereIndexVersion > 1

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Critical - P2 Critical - P2
    • 3.3.5
    • Affects Version/s: 3.0.10, 3.2.4
    • Component/s: Index Maintenance, Querying
    • Labels:
      None
    • Fully Compatible
    • ALL
    • Query 13 (04/22/16)

      Issue Summary

      With a schema and index such as the following:

      Schema
      {
        b : 1,
        d : [{
            e: 3,
            f: {
                type : "Point",
                coordinates:[-2, 53]
            }
          }
        ]
      }
      
      Index
      {
        "b" : 1,
        "d.e" : 1,
        "d.f": "2dsphere"
      }
      

      A query on these fields using elemMatch on d results in a COLLSCAN for 2dsphereIndexVersion 2 and 3 on both 3.0.10 and 3.2.4. Keeping everything else identical and switching to 2dsphereIndexVersion 1 results in the planner correctly using the index with the expected bounds.

      Reproduction

      Run the following script and verify that the explain output is a COLLSCAN. Then, change the 2dsphereIndexVersion to 1 and re-run.

      indexTest.geo.min.js
      db.indextest.drop();
      
      var row = {
        b : 1,
        d : [{
            e: 3,
            f: {
                type : "Point",
                coordinates:[-2, 53]
            }
          }
        ]
      };
      
      db.indextest.createIndex({
        "b" : 1,
        "d.e" : 1,
        "d.f": "2dsphere"
      },{
          "2dsphereIndexVersion": 2
      });
      
      db.indextest.save(row);
      
      var query = {
        b : 1,
        d : {
          $elemMatch : {
            e : 3,
            f:{
               $geoWithin : {
                 $centerSphere : [[-2, 53], 2.523219554550177E-4]
               }
             }
          }
        }
      };
      
      var explain = db.indextest.find(query).explain();
      var count = db.indextest.find(query).count();
      
      printjson(explain);
      printjson( { "count" : count } )
      

      Notes

      • Hinting the index with 2dsphereIndexVersion 2 or 3 results in the index bounds being set to [MinKey,MaxKey]

      Attached

      • Repro script
      • explain output for each 2dsphereIndexVersion, all on 3.2.4

        1. explain_2dsphereIndexVersion_1.txt
          4 kB
        2. explain_2dsphereIndexVersion_2.txt
          1 kB
        3. explain_2dsphereIndexVersion_3.txt
          1 kB
        4. indexTest.geo.min.js
          0.6 kB

            Assignee:
            david.storch@mongodb.com David Storch
            Reporter:
            bernard.gorman@mongodb.com Bernard Gorman
            Votes:
            0 Vote for this issue
            Watchers:
            12 Start watching this issue

              Created:
              Updated:
              Resolved: