Aby odpowiedzieć na twoje pierwsze pytanie:$group
czy nie zachować porządek. Istnieją otwarte prośby o zmiany, które również nieco podkreślają tło, ale nie wygląda na to, że produkt zostanie zmieniony w celu zachowania kolejności dokumentów wejściowych:
- https://jira.mongodb.org/browse/SERVER-24799
- https://jira.mongodb.org/browse/SERVER-4507
- https://jira.mongodb.org/browse/SERVER-21022
Ogólnie można powiedzieć dwie rzeczy:Generalnie chcesz najpierw pogrupować, a potem dokonać sortowania. Powodem jest to, że sortowanie mniejszej liczby elementów (które zazwyczaj tworzy grupowanie) będzie szybsze niż sortowanie wszystkich dokumentów wejściowych.
Po drugie, MongoDB dołoży wszelkich starań, aby sortować tak wydajnie i jak najmniej. dokumentacja stany:
Więc ten kod wykonuje zadanie w twoim przypadku:
collection.aggregate({
$group: {
_id: '$age',
names: { $push: '$name' }
}
}, {
$sort: {
'_id': 1
}
}, {
$limit: 10
})
EDYTUJ podążając za Twoimi komentarzami:
Zgadzam się z tym, co mówisz. Idąc trochę dalej, posunąłbym się do stwierdzenia:Jeśli $group
był wystarczająco sprytny, aby użyć indeksu, nie powinien nawet wymagać $sort
etap na początku. Niestety tak nie jest (jeszcze prawdopodobnie nie). W obecnym stanie rzeczy $group
nigdy nie użyje indeksu i nie będzie korzystał ze skrótów w oparciu o następujące etapy ($limit
w tym przypadku). Zobacz także ten link
gdzie ktoś przeprowadził podstawowe testy.
Struktura agregacji jest wciąż dość młoda, więc myślę, że włożono dużo pracy, aby potok agregacji był inteligentniejszy i szybszy.
Tutaj znajdziesz odpowiedzi na StackOverflow (np. tutaj
), gdzie ludzie sugerują użycie początkowego $sort
etap, aby "zmusić" MongoDB do użycia indeksu w jakiś sposób. To jednak znacznie spowolniło moje testy (1 milion rekordów kształtu próbki przy użyciu różnych losowych rozkładów).
Jeśli chodzi o wydajność potoku agregacji, $match
etapy na starcie są tym, co naprawdę pomaga najbardziej. Jeśli możesz ograniczyć całkowitą liczbę rekordów, które muszą przejść przez potok od samego początku, to jest to najlepsza opcja - oczywiście...;)