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

{$exists:false} on array elements returns incorrect results on MongoDB 5.0

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 5.0.0-rc3
    • Affects Version/s: 5.0.0-rc0
    • Component/s: None
    • Fully Compatible
    • ALL
    • v5.0
    • Hide

      Insert the following documents into a collection:

      db.arrays.insert({a:1})        // integer
      db.arrays.insert({a:[1]})     // array with 1 element
      db.arrays.insert({a:[1,2]})  // array with 2 elements
      

      With MongoDB 4.4.5:
      db.arrays.find({"a.0": {$exists: false)}} returns 1 document
      db.arrays.find({"a.1": {$exists: false)}} returns 2 documents
      db.arrays.find({"a.2": {$exists: false)}} returns 3 documents

      With MongoDB 5.0.0-alpha0-584-g325ff69:
      db.arrays.find({"a.0": {$exists: false)}} returns 3 documents
      db.arrays.find({"a.1": {$exists: false)}} returns 3 documents
      db.arrays.find({"a.2": {$exists: false)}} returns 3 documents

      Show
      Insert the following documents into a collection: db.arrays.insert({a:1}) // integer db.arrays.insert({a:[1]}) // array with 1 element db.arrays.insert({a:[1,2]}) // array with 2 elements With MongoDB 4.4.5: db.arrays.find({"a.0": {$exists: false )}} returns 1 document db.arrays.find({"a.1": {$exists: false )}} returns 2 documents db.arrays.find({"a.2": {$exists: false )}} returns 3 documents With MongoDB 5.0.0-alpha0-584-g325ff69: db.arrays.find({"a.0": {$exists: false )}} returns 3 documents db.arrays.find({"a.1": {$exists: false )}} returns 3 documents db.arrays.find({"a.2": {$exists: false )}} returns 3 documents
    • Query Execution 2021-06-14, Query Execution 2021-06-28

      MongoDB 5.0 returns incorrect results for queries of the form:

      { "a.0": { $exists: false } }
      

      In MongoDB 4.4 and earlier, this would return documents where the field didn't contain an array. In MongoDB 5.0, all documents are returned even if the field contains an array.

      Why does this matter? The .NET/C# driver uses this technique in its legacy LINQ implementation to determine whether a field contains a single value or an array - in particular for discriminators. Let's say we have a class D that derives from C and B. When we insert a document of type D, we will write the discriminator as {{ _t: [B,C,D] }}. If we want to find all B, but not any derived types such as C and D, we will generate the following query:

      { "_t.0" : { "$exists" : false }, _t : "B" }
      

      When querying MongoDB 4.4 and earlier, we only get documents with _t: "B" back. When querying MongoDB 5.0, we get documents of type B, C, and D back.

      While we can potentially fix this problem in the C# driver by using another technique, it will be a backwards breaking change for existing C# apps that may prevent them from upgrading to MongoDB 5.0.

            Assignee:
            andrii.dobroshynski@mongodb.com Andrii Dobroshynski (Inactive)
            Reporter:
            james.kovacs@mongodb.com James Kovacs
            Votes:
            0 Vote for this issue
            Watchers:
            15 Start watching this issue

              Created:
              Updated:
              Resolved: