För att svara på din första fråga:$group
gör inte bevara ordningen. Det finns en öppen begäran om ändringar som också framhäver bakgrunden lite men det ser inte ut som att produkten kommer att ändras för att bevara indatadokumentens ordning:
- https://jira.mongodb.org/browse/SERVER-24799
- https://jira.mongodb.org/browse/SERVER-4507
- https://jira.mongodb.org/browse/SERVER-21022
Två saker kan sägas generellt:Du vill i allmänhet gruppera först och sedan göra sorteringen. Anledningen är att sortering av färre element (som grupperingen i allmänhet producerar) kommer att gå snabbare än att sortera alla inmatade dokument.
För det andra kommer MongoDB att se till att sortera så effektivt och lite som möjligt. dokumentationen står:
Så den här koden får jobbet gjort i ditt fall:
collection.aggregate({
$group: {
_id: '$age',
names: { $push: '$name' }
}
}, {
$sort: {
'_id': 1
}
}, {
$limit: 10
})
REDIGERA efter dina kommentarer:
Jag håller med om det du säger. Och ta din logik lite längre, jag skulle gå så långt som att säga:Om $group
var smart nog att använda ett index så borde det inte ens kräva en $sort
skede i starten. Tyvärr är det inte det (inte ännu troligen). Som det ser ut idag, $group
kommer aldrig att använda ett index och det kommer inte att ta genvägar baserat på följande steg ($limit
I detta fall). Se även denna länk
där någon körde några grundläggande tester.
Aggregeringsramverket är fortfarande ganska ungt så jag antar att det pågår mycket arbete för att göra aggregeringspipelinen smartare och snabbare.
Det finns svar här på StackOverflow (t.ex. här
) där folk föreslår att man använder en $sort
i förväg steg för att "tvinga" MongoDB att använda ett index på något sätt. Detta saktade dock ner mina tester (1 miljon poster av din provform med olika slumpmässiga distributioner) avsevärt.
När det gäller prestanda för en aggregeringspipeline, $match
stadier i början är det som verkligen hjälper mest. Om du kan begränsa det totala antalet poster som måste gå igenom pipelinen från början så är det din bästa insats - självklart...;)