-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Critical - P2
-
Affects Version/s: 3.6.0-rc2
-
Component/s: Aggregation Framework, Querying
-
None
-
Fully Compatible
-
ALL
-
Query 2017-11-13
-
None
-
None
-
None
-
None
-
None
-
None
-
None
The 3.6 stable release series adds support for $expr, a way to use the aggregation expression language within a $match predicate:
https://docs.mongodb.com/master/reference/operator/query/expr/
The query engine optimizes $expr by attempting to fully or partially convert the $expr into a MatchExpression which can then be used to generate index bounds in the query planner. However, this rewrite optimization is incorrect if the $expr expresses a match over a path that contains any array whatsoever, regardless of whether the path is dotted. Consider the following example:
> db.c.drop();
> db.c.insert({a: [1, 2, 3]});
> db.c.find({$expr: {$gt: ["$a", 4]}});
// No results. This is incorrect because the array [1, 2, 3] is considered greater than
// the number 4 in the aggregation language. In fact, all arrays are considered greater
// than all numbers in aggregation, since the first part of the comparison is the
// canonical type.
// The explain shows that the match expression {a: {$gt: 4}} has been generated by
// the $expr rewrite optimization.
> db.c.find({$expr: {$gt: ["$a", 4]}}).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.c",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"a" : {
"$gt" : 4
}
},
{
"$expr" : {
"$gt" : [
"$a",
{
"$const" : 4
}
]
}
}
]
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"$and" : [
{
"a" : {
"$gt" : 4
}
},
{
"$expr" : {
"$gt" : [
"$a",
{
"$const" : 4
}
]
}
}
]
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "storchbox",
"port" : 27017,
"version" : "0.0.0",
"gitVersion" : "unknown"
},
"ok" : 1
}
The essence of the problem is that the match language has implicit array traversal semantics whereas the aggregation expression language does not. {$gt: ["$a", 4]} and {a: {$gt: 4}} may look the same syntactically, but their meanings are not equivalent.
- is related to
-
SERVER-31760 Lookup sub-pipeline is not using index for equality match
-
- Closed
-