ISSUE SUMMARY
Queries which have the format below fail when there's an index reaching into the deepest subfield (y.z). The format is triggered by an $and operator that contains an $elemMatch with any indexed logical operator below it. This includes indexed $or, $not, and $ne below $elemMatch. For example:
db.test.find({x: 1, $and: [{y: {'$elemMatch': {'$or': [{z: 3}]}}}]})
|
USER IMPACT
Queries of this type will fail with an assertion error.
WORKAROUNDS
Rewrite the query if possible to avoid $elemMatch over the logical operator (e.g.: $or):
db.test.find({x: 1, $and: [{y: {'$elemMatch': {'$or': [{z: 3}, {z:4}]}}}]})
|
can be rewritten as:
db.test.find({x: 1, $and: [{$or: [{"y.z": 3}, {"y.z":4}]}]})
|
AFFECTED VERSIONS
MongoDB production releases 2.6.0 and 2.6.1 are affected.
FIX VERSION
The fix is included in the 2.6.2 production release.
RESOLUTION DETAILS
The special $elemMatch object handling now accounts for predicates tagged by the enumerator that are below non-bounds generating MatchExpression nodes. Previously, this code skipped these tagged predicates, producing zero index scan leafs as a result (causing us to hit the assertion which makes sure there is at least one index scan).