Queries are represented internally as a MatchExpression tree, which has a toBSON method that, when given a BSONObjBuilder, serializes the tree and produces a BSONObj representing the query. At the moment, there are several types of MatchExpression ($not, particularly) that do not serialize to valid query objects, and thus parsing the result of a toBSON call will result in an error. It should be the case that any MatchExpression can be roundtripped through BSON and will result in a new MatchExpression that is logically equivalent to the first.
Note:
Most of the difficulties for this ticket are because of our complex $not semantics. Rather than go through complex logic in the parser or serialization code, we instead opted to always turn a $not into the following structure:
{$not: {...}} --> {$nor: [{$and: [...]}]}
While logically equivalent, the query planner is unable to perform the same level of optimization with a $nor as with a $not. At the moment, MatchExpression::toBSON is only being used in aggregation pipeline optimization, so as a result of this workaround, any $match stage that is roundtripped through BSON and involves a $not may not be correctly optimized for in the query planner, and will give unexpected explain() output. A solution to this problem is to update CanonicalQuery::normalizeTree() to recognize that a $nor with one child is logically equivalent to a $not, and perform that swap.
- depends on
-
SERVER-12307 Provide a means in query framework to efficiently determine if a query is $isolated
- Closed
- is depended on by
-
SERVER-19415 PlanCache.listQueryShapes() reports the wrong query predicates for $or queries that use the SubplanStage
- Closed
-
SERVER-20506 Conditionally order $match with $unwind
- Closed
- is duplicated by
-
SERVER-25485 explain shows incorrect parsed syntax for $elemMatch filter
- Closed
- related to
-
SERVER-27649 Don't error on serialization of $elemMatch with $regex
- Closed