Mám podezření, že problém nebyl v tom, že by agregace přerušila index, ale místo toho, že agregace nepoužívala indexy a provedla skenování kolekce.
Agregace mohou využívat výhody indexů, pokud existují $ fáze zápasu a/nebo $sort
umístěn na začátku potrubí. Tato agregace je pouze jedna $group
fázi, což znamená, že k výpočtu počtu by bylo nutné iterovat celou kolekci.
Níže uvádím jednoduchý příklad, který ukazuje, jak agregace provádí skenování kolekce, i když je pole pole indexováno.
> db.foo.insert({ "x" : [ 1, 2 ] } )
> db.foo.insert({ "x" : [ 1 ] } )
> db.foo.createIndex({ "x" : 1 } )
...
> db.foo.aggregate([ { $group: { _id: null, cnt: { $sum : { $size: "$x" } } } } ] )
{ "_id" : null, "cnt" : 3 }
// Results of a .explain() - see 'winningPlan' below
> db.foo.explain(true).aggregate([ { $group: { _id: null, cnt: { $sum : { $size: "$x" } } } } ] )
{
"stages" : [
{
"$cursor" : {
"query" : {
},
"fields" : {
"x" : 1,
"_id" : 0
},
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "stack.foo",
"indexFilterSet" : false,
"parsedQuery" : {
},
"winningPlan" : {
"stage" : "COLLSCAN",
"direction" : "forward"
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 2,
"executionTimeMillis" : 0,
"totalKeysExamined" : 0,
"totalDocsExamined" : 2,
"executionStages" : {
"stage" : "COLLSCAN",
"nReturned" : 2,
"executionTimeMillisEstimate" : 0,
"works" : 4,
"advanced" : 2,
"needTime" : 1,
"needYield" : 0,
"saveState" : 1,
"restoreState" : 1,
"isEOF" : 1,
"invalidates" : 0,
"direction" : "forward",
"docsExamined" : 2
},
"allPlansExecution" : [ ]
}
}
},
{
"$group" : {
"_id" : {
"$const" : null
},
"cnt" : {
"$sum" : {
"$size" : [
"$x"
]
}
}
}
}
],
"ok" : 1,
...
}