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

Plans using $** wildcard indices can return duplicate results

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major - P3
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 4.1.4
    • Component/s: Querying
    • Labels:
      None
    • Backwards Compatibility:
      Fully Compatible
    • Operating System:
      ALL
    • Steps To Reproduce:
      Hide

      (function() {
          "use strict";
       
          db.c.drop();
          assert.commandWorked(db.c.insert({a: {b: 1, c: 1}}));
          assert.eq(1, db.c.find({a: {$exists: true}}).itcount());
       
          assert.commandWorked(db.c.createIndex({"$**": 1}));
          assert.eq(1, db.c.find({a: {$exists: true}}).itcount());
      }());
      

      Show
      (function() { "use strict";   db.c.drop(); assert.commandWorked(db.c.insert({a: {b: 1, c: 1}})); assert.eq(1, db.c.find({a: {$exists: true}}).itcount());   assert.commandWorked(db.c.createIndex({"$**": 1})); assert.eq(1, db.c.find({a: {$exists: true}}).itcount()); }());
    • Sprint:
      Query 2018-10-08, Query 2018-10-22

      Description

      The query planner instructs an IXSCAN (or other index access stage) to deduplicate based on whether the index is multikey. $** indices, however, may contain multiple keys for a document in the absence of arrays. Consider the example of a collection which contains the document {a: {b: 1, c: 1}} with the index {"$**": 1}. The index will contain the following keys, both referring to the same document:

      • {$_path: "a.b", "a.b": 1}
      • {$_path: "a.c", "a.c": 1}

      The planner, however, will generate an IndexEntry which is not marked as multikey, since there are no array paths:

      https://github.com/mongodb/mongo/blob/175f5e3c25ddba439b7d28254a4af5504aded0d8/src/mongo/db/query/planner_ixselect.cpp#L103-L110

      As a result, a $** IXSCAN used to answer a query for which both of the index keys are in bounds will fail to deduplicate. The only known predicate for which this can happen is $exists. See the repro steps below for an example query that returns the same document twice.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              yuta.arai Yuta Arai
              Reporter:
              david.storch David Storch
              Participants:
              Votes:
              0 Vote for this issue
              Watchers:
              8 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: