Chcete-li odpovědět na svou první otázku:$group
není zachovat pořádek. Existují otevřené požadavky na změny, které také trochu zvýrazňují pozadí, ale nezdá se, že by se produkt změnil, aby se zachovalo pořadí vstupních dokumentů:
- https://jira.mongodb.org/browse/SERVER-24799
- https://jira.mongodb.org/browse/SERVER-4507
- https://jira.mongodb.org/browse/SERVER-21022
Obecně lze říci dvě věci:Obecně chcete nejprve seskupovat a poté třídit. Důvodem je, že třídění menšího počtu prvků (které seskupování obecně produkuje) bude rychlejší než třídění všech vstupních dokumentů.
Za druhé, MongoDB se postará o to, aby třídilo co nejefektivněji a co nejméně. dokumentace uvádí:
Tento kód tedy ve vašem případě dokončí práci:
collection.aggregate({
$group: {
_id: '$age',
names: { $push: '$name' }
}
}, {
$sort: {
'_id': 1
}
}, {
$limit: 10
})
UPRAVIT podle vašich komentářů:
Souhlasím s tím, co říkáte. A když vezmu vaši logiku trochu dále, šel bych tak daleko, že bych řekl:Pokud $group
byl dostatečně chytrý na to, aby používal index, pak by ani neměl vyžadovat $sort
etapa na startu. Bohužel není (zatím asi ne). Jak se věci dnes mají, $group
nikdy nepoužije index a nebude používat zkratky založené na následujících fázích ($limit
v tomto případě). Podívejte se také na tento odkaz
kde někdo provedl základní testy.
Agregační rámec je stále docela mladý, takže si myslím, že je třeba udělat hodně práce, aby byl agregační kanál chytřejší a rychlejší.
Zde jsou odpovědi na StackOverflow (např. zde
), kde lidé navrhují použít předem $sort
fázi, abychom MongoDB nějak „donutili“ používat index. To však výrazně zpomalilo mé testy (1 milion záznamů tvaru vašeho vzorku pomocí různých náhodných distribucí).
Pokud jde o výkon agregačního kanálu, $match
fáze na startu jsou to, co opravdu pomáhá nejvíce. Pokud můžete omezit celkový počet záznamů, které musí projít potrubím od začátku, pak je to vaše nejlepší sázka - samozřejmě...;)