Object $elemMatch should not match arrays under an array

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Minor - P4
    • None
    • Affects Version/s: None
    • Component/s: None
    • Query Optimization
    • None
    • 3
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      ElemMatchObjectMatchExpression is supposed to match arrays which have an object element satisfying the sub-predicates. However, there are some edge cases where it will match arrays which have an array element satisfying the sub-predicates. For example:

      > db.foo.find()
      { "_id" : 0, "a" : [ [ ] ] }
      { "_id" : 1, "a" : [ [ { "b" : 1 } ] ] }
      { "_id" : 2, "a" : [ { "b" : 1 } ] }
      
      // Object $elemMatch with an empty object
      > db.foo.find({a: {$elemMatch: {}}})
      { "_id" : 0, "a" : [ [ ] ] }
      { "_id" : 1, "a" : [ [ { "b" : 1 } ] ] }
      { "_id" : 2, "a" : [ { "b" : 1 } ] }
      
      // Somewhat surprisingly, this is also an object $elemMatch
      > db.foo.find({a: {$elemMatch: {$or: [{$alwaysTrue: 1}]}}})
      { "_id" : 0, "a" : [ [ ] ] }
      { "_id" : 1, "a" : [ [ { "b" : 1 } ] ] }
      { "_id" : 2, "a" : [ { "b" : 1 } ] }
      

      The hypothesis is that this is a mistake due to this line, which returns true for both objects and arrays.

      The current behavior is consistent across all of our query frameworks. The proposal is to change the behavior for all query frameworks so that ElemMatchObjectMatchExpression only matches nested objects:

      > db.foo.find({a: {$elemMatch: {}}})
      { "_id" : 2, "a" : [ { "b" : 1 } ] }
      
      > db.foo.find({a: {$elemMatch: {$or: [{$alwaysTrue: 1}]}}})
      { "_id" : 2, "a" : [ { "b" : 1 } ] }
      

              Assignee:
              [DO NOT USE] Backlog - Query Optimization
              Reporter:
              Hana Pearlman
              Votes:
              0 Vote for this issue
              Watchers:
              8 Start watching this issue

                Created:
                Updated: