ISSUE SUMMARY
Queries which have the format below fail when there's an index reaching into the deepest subfield. The format is an $elemMatch operator that has an $all descendent, which in turn has another $elemMatch inside:
db.coll.find({z: 1, "a.b": {$elemMatch: {c: {$all: [{$elemMatch: {d: 0}}]}}}})
USER IMPACT
Low user impact due to the very specific format of the query required to trigger the bug.
WORKAROUNDS
If the $all operator is rewritten as an $and this issue is not triggered:
db.coll.find({z: 1, "a.b": {$elemMatch: {$and: [{c: [{$elemMatch: {d: 0}}]}]}}})
RESOLUTION
The bug arose from the query planner failing to consider predicates nested inside an $elemMatch-$all-$elemMatch chain. The planner logic was adjusted so that these predicates are no longer ignored.
AFFECTED VERSIONS
Version 2.6.0 is affected by this issue.
PATCHES
The patch is included in the 2.6.1 production release.
Original description
See the code here:
This function collects predicates from inside an $elemMatch object. Right now it traverses deeply through AND nodes and other ELEM_MATCH_OBJECT nodes. It should also traverse deeply through ALL. Failing to do so means that the access planner might miss predicates which are tagged to use the index, and hence fail to properly build the access plan.