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

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

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major - P3
    • Resolution: Fixed
    • Affects Version/s: 5.0.0-rc0
    • Fix Version/s: 5.0.0-rc3
    • Component/s: None
    • Labels:
    • Backwards Compatibility:
      Fully Compatible
    • Operating System:
      ALL
    • Backport Requested:
      v5.0
    • Steps To Reproduce:
      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
    • Sprint:
      Query Execution 2021-06-14, Query Execution 2021-06-28

      Description

      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.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              andrii.dobroshynski Andrii Dobroshynski
              Reporter:
              james.kovacs James Kovacs
              Participants:
              Votes:
              0 Vote for this issue
              Watchers:
              14 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: