Om je eerste vraag te beantwoorden:$group
doet niet de orde bewaren. Er zijn openstaande verzoeken om wijzigingen die ook de achtergronden een beetje benadrukken, maar het ziet er niet naar uit dat het product zal worden gewijzigd om de volgorde van de invoerdocumenten te behouden:
- https://jira.mongodb.org/browse/SERVER-24799
- https://jira.mongodb.org/browse/SERVER-4507
- https://jira.mongodb.org/browse/SERVER-21022
Over het algemeen kunnen twee dingen worden gezegd:u wilt over het algemeen eerst groeperen en vervolgens sorteren. De reden hiervoor is dat het sorteren van minder elementen (die de groepering over het algemeen produceert) sneller gaat dan het sorteren van alle invoerdocumenten.
Ten tweede gaat MongoDB ervoor zorgen dat er zo efficiënt en zo min mogelijk wordt gesorteerd. De documentatie staten:
Dus deze code klaart de klus in jouw geval:
collection.aggregate({
$group: {
_id: '$age',
names: { $push: '$name' }
}
}, {
$sort: {
'_id': 1
}
}, {
$limit: 10
})
BEWERKEN naar aanleiding van uw opmerkingen:
Ik ben het eens met wat je zegt. En als ik nog een beetje verder ga met je logica, zou ik zo ver gaan als te zeggen:Als $group
slim genoeg was om een index te gebruiken, dan zou het niet eens een $sort
moeten vereisen stadium bij de start. Helaas is het dat niet (nog niet waarschijnlijk). Zoals de zaken er vandaag voor staan, $group
zal nooit een index gebruiken en er zijn geen snelkoppelingen nodig op basis van de volgende fasen ($limit
in dit geval). Zie ook deze link
waar iemand enkele basistests heeft uitgevoerd.
Het aggregatieraamwerk is nog vrij jong, dus ik denk dat er veel werk wordt verzet om de aggregatiepijplijn slimmer en sneller te maken.
Er zijn antwoorden hier op StackOverflow (bijv. hier
) waar mensen voorstellen om een vooraf $sort
. te gebruiken stage om MongoDB te "dwingen" om op de een of andere manier een index te gebruiken. Dit vertraagde echter mijn tests (1 miljoen records van uw steekproefvorm met verschillende willekeurige verdelingen) aanzienlijk.
Als het gaat om de prestaties van een aggregatiepijplijn, $match
fasen aan het begin zijn wat echt het meest helpt. Als je het totale aantal records dat vanaf het begin door de pijplijn moet gaan, kunt beperken, dan is dat de beste keuze - natuurlijk...;)