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

The $where operator should not be allowed under $elemMatch

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major - P3
    • Resolution: Fixed
    • Affects Version/s: 2.6.0-rc3
    • Fix Version/s: 2.6.1, 2.7.0
    • Component/s: Querying
    • Labels:
    • Backwards Compatibility:
      Major Change
    • Operating System:
      ALL
    • Backport Completed:

      Description

      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 } ] }

        Attachments

          Issue Links

            Activity

              People

              • Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: