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

The $where operator should not be allowed under $elemMatch

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 2.6.1, 2.7.0
    • Affects Version/s: 2.6.0-rc3
    • Component/s: Querying
    • Major Change
    • ALL

      Issue Status as of April 17, 2014

      ISSUE SUMMARY
      The $where operator applies to top-level elements only, however in 2.4 the specific implementation allowed usage under a sub-field within the $elemMatch operator as an edge case. This behavior was unintentional. With the introduction of the new query engine in 2.6 the $where usage should have been removed in the $elemMatch operator. The special case of $where as the first condition was missed.

      USER IMPACT
      As the behavior has changed from 2.4.9 some queries relying on the $where operator in $elemMatch may no longer work and return an error instead.

      WORKAROUNDS
      In most cases, a rewrite of the query and replacement of $where clauses in the $elemMatch document should be possible.

      RESOLUTION
      Consistent rejection of the $where operator anywhere in $elemMatch queries, with a clear error message.

      AFFECTED VERSIONS
      Version 2.6.0 was affected by this bug.

      PATCHES
      The patch is included in the 2.6.1 production release.

      Original description

      If the first listed condition in an $elemMatch is a $where predicate, the query will not parse.

      > db.version()
      2.6.0-rc3
      > db.foo.insert({a:[{b:1,c:2},{b:2,c:1}]})
      WriteResult({ "nInserted" : 1 })
      > db.foo.insert({a:[{b:1,c:1}]})
      WriteResult({ "nInserted" : 1 })
      > db.foo.find({a:{$elemMatch:{b:1,$where:'this.c==1;'}}})
      { "_id" : ObjectId("5342e26193252aaba7ab9f74"), "a" : [ { "b" : 1, "c" : 1 } ] }
      > db.foo.find({a:{$elemMatch:{$where:'this.c==1;',b:1}}})
      error: {
      	"$err" : "Can't canonicalize query: BadValue unknown operator: $where",
      	"code" : 17287
      }
      

      The query parses correctly in 2.4.9.

      > db.version()
      2.4.9
      > db.foo.find({a:{$elemMatch:{$where:'this.c==1;',b:1}}})
      { "_id" : ObjectId("5342e26193252aaba7ab9f74"), "a" : [ { "b" : 1, "c" : 1 } ] }
      

            Assignee:
            benety.goh@mongodb.com Benety Goh
            Reporter:
            rassi J Rassi
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: