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

Handle filter equal to null in dotted paths correctly

    • Type: Icon: Bug Bug
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • Query Execution
    • ALL

      When we have a document like a record

      {_id: 0,  time: new Date(1680912440), a: [1, "string", 4]}
      

      and a query

      {"a.b": {$eq: null}}
      

      , block processing returns this record. SBE without block processing and classic engine do not.

      In SBE without block processing the logic is that every element in this array is checked against the predicate and since none qualifies, the whole document does not qualify. In block processing, when we extract the values from the block we check if there are values in the path a.b and since there are not, we store Nothing for this document. When we later evaluate this document the predicate is satisfied and the document is included in the result set.

      If we have another document 

      {_id: 1, time: new Date(1680912440+100), a: [1, "string", 4, {}]}

      , all engines include this document. The logic is that the empty object in the array satisfies the predicate so the whole document satisfies the predicate.

      In block processing we cannot distinguish the two cases. We should change how the non existence of the element is represented to satisfy the semantics of dotted paths.

      Data

      db.createCollection( "arrColl", { timeseries:{ timeField: "time" }})
      db.arrColl.insertOne({_id: 0, time: new Date(1680912440), a: [1, "string", 4]})
      db.arrColl.insertOne({_id: 0, time: new Date(1680912440+100), a: [1, "string", 4, {}]})
      

      Queries and results

      db.arrColl.aggregate([{$project:{_id:1, a:1}},{$match: {"a.b": {$eq: null}}}])

      (with block version of typeMatch)

      [
      { _id: 0, a: [ 1, 'string', 4 ] },
      { _id: 1, a: [ 1, 'string', 4, {} ] }
      ]
      

      (in master)

      [ { _id: 1, a: [ 1, 'string', 4, {} ] } ]

      (no SBE)

      db.arrColl.find({"a.b": {$eq: null}})
      [ {time: ISODate("1970-01-20T10:55:12.540Z"), _id: 1, a: [ 1, 'string', 4, {} ]} ]

            Assignee:
            Unassigned Unassigned
            Reporter:
            foteini.alvanaki@mongodb.com Foteini Alvanaki
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: