|
The latter aggregation is semantically equivalent to the following count operation:
> db.c.explain().count({username: /^a/});
|
{
|
"queryPlanner" : {
|
"plannerVersion" : 1,
|
"namespace" : "test.c",
|
"indexFilterSet" : false,
|
"parsedQuery" : {
|
"username" : {
|
"$regex" : "^a"
|
}
|
},
|
"winningPlan" : {
|
"stage" : "COUNT",
|
"inputStage" : {
|
"stage" : "FETCH",
|
"inputStage" : {
|
"stage" : "IXSCAN",
|
"keyPattern" : {
|
"username" : 1
|
},
|
"indexName" : "username_1",
|
"isMultiKey" : false,
|
"multiKeyPaths" : {
|
"username" : [ ]
|
},
|
"isUnique" : false,
|
"isSparse" : false,
|
"isPartial" : false,
|
"indexVersion" : 2,
|
"direction" : "forward",
|
"indexBounds" : {
|
"username" : [
|
"[\"a\", \"b\")",
|
"[/^a/, /^a/]"
|
]
|
}
|
}
|
}
|
},
|
"rejectedPlans" : [ ]
|
},
|
"serverInfo" : {
|
"host" : "dstorch",
|
"port" : 27017,
|
"version" : "0.0.0",
|
"gitVersion" : "unknown"
|
},
|
"ok" : 1
|
}
|
The explain shows that the count plan also has an unnecessary FETCH stage. Since the aggregation system uses the planner's count path for this query, these two issues have the same root cause. The issue is already tracked here: SERVER-17148. But since SERVER-17148 is kind of an odd umbrella ticket for multiple optimizations, I'll leave this ticket open and mark them as related.
|
|
Plans for two:
MongoDB Enterprise alt4:PRIMARY> db.t1.explain().aggregate([ {$match:{username:/^a/}}, {$group:{_id:"$username",count:{$sum:1}}}])
|
{
|
"stages" : [
|
{
|
"$cursor" : {
|
"query" : {
|
"username" : /^a/
|
},
|
"fields" : {
|
"username" : 1,
|
"_id" : 0
|
},
|
"queryPlanner" : {
|
"plannerVersion" : 1,
|
"namespace" : "test.t1",
|
"indexFilterSet" : false,
|
"parsedQuery" : {
|
"username" : /^a/
|
},
|
"winningPlan" : {
|
"stage" : "PROJECTION",
|
"transformBy" : {
|
"username" : 1,
|
"_id" : 0
|
},
|
"inputStage" : {
|
"stage" : "IXSCAN",
|
"keyPattern" : {
|
"username" : 1
|
},
|
"indexName" : "username_1",
|
"isMultiKey" : false,
|
"multiKeyPaths" : {
|
"username" : [ ]
|
},
|
"isUnique" : false,
|
"isSparse" : false,
|
"isPartial" : false,
|
"indexVersion" : 2,
|
"direction" : "forward",
|
"indexBounds" : {
|
"username" : [
|
"[\"a\", \"b\")",
|
"[/^a/, /^a/]"
|
]
|
}
|
}
|
},
|
"rejectedPlans" : [ ]
|
}
|
}
|
},
|
{
|
"$group" : {
|
"_id" : "$username",
|
"count" : {
|
"$sum" : {
|
"$const" : 1
|
}
|
}
|
}
|
}
|
],
|
"ok" : 1
|
}
|
MongoDB Enterprise alt4:PRIMARY> db.t1.explain().aggregate([ {$match:{username:/^a/}}, {$group:{_id:null,count:{$sum:1}}}])
|
{
|
"stages" : [
|
{
|
"$cursor" : {
|
"query" : {
|
"username" : /^a/
|
},
|
"queryPlanner" : {
|
"plannerVersion" : 1,
|
"namespace" : "test.t1",
|
"indexFilterSet" : false,
|
"parsedQuery" : {
|
"username" : /^a/
|
},
|
"winningPlan" : {
|
"stage" : "FETCH",
|
"inputStage" : {
|
"stage" : "IXSCAN",
|
"keyPattern" : {
|
"username" : 1
|
},
|
"indexName" : "username_1",
|
"isMultiKey" : false,
|
"multiKeyPaths" : {
|
"username" : [ ]
|
},
|
"isUnique" : false,
|
"isSparse" : false,
|
"isPartial" : false,
|
"indexVersion" : 2,
|
"direction" : "forward",
|
"indexBounds" : {
|
"username" : [
|
"[\"a\", \"b\")",
|
"[/^a/, /^a/]"
|
]
|
}
|
}
|
},
|
"rejectedPlans" : [ ]
|
}
|
}
|
},
|
{
|
"$group" : {
|
"_id" : {
|
"$const" : null
|
},
|
"count" : {
|
"$sum" : {
|
"$const" : 1
|
}
|
}
|
}
|
}
|
],
|
"ok" : 1
|
}
|
This may be a duplicate but I didn't find a match.
|