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

Incorrect index bounds for {$ne: ["String"]} query

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Critical - P2
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 4.1.9
    • Component/s: Querying
    • Labels:
    • Backwards Compatibility:
      Fully Compatible
    • Operating System:
      ALL
    • Backport Requested:
      v4.0, v3.6, v3.4, v3.2
    • Steps To Reproduce:
      Hide

      Saving this file as repro.js:

      (function() { 
        "use strict"; 
       
       
        const coll = db.reproducer; 
        coll.drop(); 
       
       
        assert.commandWorked(coll.insert([{_id: 0, str: "Avon"}])); 
       
       
        assert.eq(1, coll.find({str: {$ne: ["Avon"]}}).itcount()); 
        assert.commandWorked(coll.ensureIndex({str: 1})); 
        assert.eq(1, coll.find({str: {$ne: ["Avon"]}}).itcount()); // FAILS 
      })();
      

      You can reproduce this failure with

      python buildscripts/resmoke.py repro.js
      

      Show
      Saving this file as repro.js : ( function () {   "use strict" ;       const coll = db.reproducer;   coll.drop();       assert.commandWorked(coll.insert([{_id: 0, str: "Avon" }]));       assert.eq(1, coll.find({str: {$ne: [ "Avon" ]}}).itcount());   assert.commandWorked(coll.ensureIndex({str: 1}));   assert.eq(1, coll.find({str: {$ne: [ "Avon" ]}}).itcount()); // FAILS })(); You can reproduce this failure with python buildscripts/resmoke.py repro.js
    • Sprint:
      Query 2019-02-25
    • Linked BF Score:
      7

      Description

      For a query like

      {x: {$not: {$in: [["String"]]}}
      

      a collection scan will return the document

      {x: "String"}
      

      because "String" != ["String"] and so "String" is not in the array [["String"]]. However, if you build an index on {x: 1} then the above document is not returned. Using explain, you can see the index bounds are:

      {
         "x" : [
         	"[MinKey, \"String\")",
         	"(\"String\", [ \"String\" ])",
         	"([ \"String\" ], MaxKey]"
         ]
      }
      

      Compare this to what should be the equivalent query

      {x: {$ne: ["String"]}}
      

      we then get the bounds:

      {
      	"x" : [
      		"[MinKey, [ \"String\" ])",
      		"([ \"String\" ], [ [ \"String\" ] ])",
      		"([ [ \"String\" ] ], MaxKey]"
      	]
      }
      

      It looks like the index bounds building logic for an $in within a $not.

        Attachments

          Activity

            People

            • Votes:
              0 Vote for this issue
              Watchers:
              11 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: