Подозирам, че проблемът не е, че агрегацията ще разбие индекс, а вместо това, че агрегацията не използва индекси и ще извърши сканиране на колекция.
Агрегациите могат да се възползват от индексите, когато има $ съпоставяне и/или етапи на $sort
поставен в началото на тръбопровод. Това агрегиране е само една $group
етап, което означава, че цялата колекция ще трябва да бъде повторена, за да се изчисли броят.
Поставям прост пример по-долу, показващ агрегирането, извършващо сканиране на колекция, дори когато полето на масива е индексирано.
> 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,
...
}