$sort, $limit en $skip in de pipeline
U ordent en pagineert aggregatieresultaten en begrijpt de optimalisatieregels voor het vóór $group plaatsen van $match en $sort.
$sort, $limit en $skip in de pipeline is een gratis MongoDB Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject MongoDB Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus MongoDB Academy bevat in totaal 4 lessen.
Overzicht: resultaten ordenen en pagineren
Drie fasen van de aggregatiepijplijn bepalen de volgorde en hoeveelheid van de resultaten: $sort ordent documenten op basis van een of meer velden, $limit neemt alleen de eerste N documenten, en $skip verwijdert de eerste N documenten. Samen implementeren ze sortering en paginering. Als je begrijpt waar je ze in de pijplijn plaatst, kan dat een grote invloed hebben op de prestaties.
De fase $sort
De fase $sort ordent documenten op basis van de waarden van een of meer velden. Gebruik 1 voor oplopende en -1 voor aflopende volgorde. Als er meerdere velden zijn opgegeven, worden documenten eerst op het eerste veld gesorteerd, vervolgens bij gelijke waarden op het tweede veld, enzovoort — precies zoals bij sortering op meerdere sleutels in SQL of MongoDB's find().sort().
// Sort by revenue descending, then alphabetically by name for ties
db.products.aggregate([
{ $group: { _id: '$category', revenue: { $sum: '$price' } } },
{ $sort: { revenue: -1, _id: 1 } } // revenue desc, category name asc
]);$sort en indexgebruik
Wanneer $sort de eerste fase van de pijplijn is (of volgt op een $match die een index gebruikt), kan MongoDB een index gebruiken om aan de sortering te voldoen. Zo wordt een sortering in het geheugen volledig vermeden. Wanneer $sort volgt op fasen die nieuwe velden produceren, zoals $group of $project, is er geen index beschikbaar en voert MongoDB een sortering in het geheugen uit. Voor grote sorteringen in het geheugen (>100 MB) is allowDiskUse: true vereist.
// Index-backed sort: $sort on indexed field before any transformation
db.orders.aggregate([
{ $match: { userId: 'u1' } },
{ $sort: { createdAt: -1 } } // if createdAt is indexed, no in-memory sort
]);
// In-memory sort: $sort after $group (computed field, no index)
db.orders.aggregate([
{ $group: { _id: '$userId', total: { $sum: '$amount' } } },
{ $sort: { total: -1 } } // in-memory: 'total' is a computed field
]);De fase $limit
$limit geeft alleen de eerste N documenten door aan de volgende fase en verwijdert de rest. Het gebruik is eenvoudig: geef een geheel getal op dat het maximumaantal documenten aangeeft dat mag worden doorgelaten. Als je $limit vóór dure fasen zoals $lookup plaatst, verklein je het aantal uitgevoerde koppelingen of opzoekingen aanzienlijk. Vraag jezelf altijd af: 'Kan ik eerder beperken?'
// Top 10 best-selling products
db.orders.aggregate([
{ $group: { _id: '$productId', sold: { $sum: '$qty' } } },
{ $sort: { sold: -1 } },
{ $limit: 10 }, // only top 10 pass through
// Only 10 lookups instead of thousands:
{ $lookup: { from: 'products', localField: '_id', foreignField: '_id', as: 'product' } }
]);De fase $skip
$skip verwijdert de eerste N documenten uit de stroom. Dit is het aggregatie-equivalent van paginering met een verschuivingswaarde: pagina 2 begint bij skip 10 (uitgaande van 10 resultaten per pagina). $skip komt altijd na $sort om consistente resultaten te krijgen — het overslaan van ongesorteerde documenten levert onvoorspelbare pagina's op. Net als SQL OFFSET is $skip bij grote verschuivingswaarden traag, omdat MongoDB alle overgeslagen documenten nog steeds moet verwerken.
const PAGE = 2;
const PAGE_SIZE = 10;
db.articles.aggregate([
{ $match: { status: 'published' } },
{ $sort: { publishedAt: -1 } },
{ $skip: (PAGE - 1) * PAGE_SIZE }, // skip page 1's 10 docs
{ $limit: PAGE_SIZE } // take page 2's 10 docs
]);Optimalisatie: samenvoegen van $sort en $limit
De aggregatie-optimalisatie van MongoDB detecteert wanneer een fase $sort direct wordt gevolgd door een fase $limit en voegt deze samen tot een top-N-sortering. In plaats van alle documenten te sorteren en daarna de meeste te verwijderen, bewaart MongoDB tijdens het sorteren alleen de N beste kandidaten in een prioriteitswachtrij. Dit gebruikt O(N) geheugen in plaats van O(totaal) geheugen. Deze optimalisatie gebeurt automatisch: je krijgt dit gedrag door eenvoudig $sort gevolgd door $limit te schrijven.
// This pattern triggers the top-N sort optimisation
db.reviews.aggregate([
{ $match: { productId: 'p1' } },
{ $sort: { rating: -1, helpful: -1 } }, // sort
{ $limit: 5 } // $sort + $limit merged into top-5 sort internally
]);
// MongoDB never sorts ALL reviews; it tracks only the best 5Optimalisatie: volgorde van $match en $sort aanpassen
De aggregatie-optimalisatie verplaatst een fase $match ook automatisch eerder in de pijplijn wanneer dat veilig is. Als $sort bijvoorbeeld vóór $match staat voor een veld dat $sort niet heeft berekend, verplaatst de optimalisatie $match vóór $sort. Zo wordt het aantal documenten dat moet worden gesorteerd kleiner. Je kunt wijzigingen door de optimalisatie bekijken in de uitvoer van explain().
// You write:
db.orders.aggregate([
{ $sort: { amount: -1 } },
{ $match: { status: 'completed' } } // optimizer moves this BEFORE $sort
]);
// Optimized execution (equivalent to):
db.orders.aggregate([
{ $match: { status: 'completed' } }, // fewer docs to sort
{ $sort: { amount: -1 } }
]);Alle vier combineren: een volledig lijst-eindpunt
Een realistisch API-eindpunt dat producten met filters, sortering en paginering weergeeft, combineert $match, $sort, $skip en $limit in de juiste volgorde. Het patroon is altijd: filteren → sorteren → overslaan → beperken. Dankzij deze volgorde gebruikt MongoDB indexen voor zowel het filteren als, waar mogelijk, het sorteren voordat onnodige documenten worden verwijderd.
async function getProducts({ category, sort = 'price', page = 1, pageSize = 20 }) {
return db.products.aggregate([
{ $match: { category, inStock: true } }, // 1. filter
{ $sort: { [sort]: 1 } }, // 2. sort
{ $skip: (page - 1) * pageSize }, // 3. offset
{ $limit: pageSize } // 4. take page
]).toArray();
}Prestaties van $skip bij diepe verschuivingswaarden
Het fundamentele probleem met $skip is dat MongoDB elk overgeslagen document nog steeds moet verwerken en verwijderen. Op pagina 1000 met 20 items per pagina verwijdert MongoDB 19.980 documenten voordat het 20 documenten retourneert. Dit wordt steeds trager naarmate je verder door de pagina's gaat. Voor openbare zoek- of feed-API's waarbij gebruikers zelden verder gaan dan pagina 5–10, is paginering met een verschuivingswaarde prima. Voor frequente paginering op diepe posities is paginering op basis van een sleutel vereist.
// Page 1000 is SLOW: MongoDB processes and discards 19,980 docs
db.posts.aggregate([
{ $sort: { createdAt: -1 } },
{ $skip: 19980 }, // 999 * 20
{ $limit: 20 }
]);
// Keyset pagination: always fast regardless of page depth
db.posts.aggregate([
{ $match: { createdAt: { $lt: lastSeenTimestamp } } }, // cursor
{ $sort: { createdAt: -1 } },
{ $limit: 20 }
]);Geheugenlimiet van $sort en allowDiskUse
Een $sort in het geheugen binnen de aggregatiepijplijn is standaard beperkt tot 100 MB. Als de sortering deze limiet overschrijdt, mislukt de pijplijn met de fout QueryExceededMemoryLimitNoDiskUseAllowed. Geef { allowDiskUse: true } op als tweede argument van aggregate() om het tijdelijk wegschrijven naar schijf in te schakelen. Je kunt ook vroegtijdig een $match toepassen of een ondersteunende index gebruiken om de grootte van de invoer voor de sortering te verkleinen.
// Enable disk use for large sorts
db.events.aggregate(
[
{ $match: { year: 2024 } },
{ $sort: { timestamp: -1 } },
{ $group: { _id: '$userId', events: { $push: '$type' } } }
],
{ allowDiskUse: true } // allows spilling to disk
);Het totale aantal naast de resultaten ophalen
Een veelgebruikt patroon voor API's is om zowel de gepagineerde resultaten als het totale aantal in één communicatie met de database terug te geven. Gebruik $facet om de pijplijn op te splitsen in twee parallelle vertakkingen: één voor de resultaten met $skip/$limit en één voor $count. Zo vermijd je twee afzonderlijke aggregatieaanroepen en is dit efficiënter dan alle documenten afzonderlijk te tellen.
db.products.aggregate([
{ $match: { category: 'electronics' } },
{ $sort: { price: 1 } },
{ $facet: {
// Branch 1: paginated results
data: [
{ $skip: 0 },
{ $limit: 20 }
],
// Branch 2: total count
total: [
{ $count: 'count' }
]
}}
]);
// Output: { data: [...20 docs...], total: [{ count: 348 }] }Korte toets
Toets je inzicht in $sort, $limit en $skip in de aggregatiepijplijn.
Samenvatting van de les
In deze les heb je geleerd dat $sort documenten ordent en profiteert van indexgebruik wanneer je deze fase vroeg plaatst, dat $limit de eerste N documenten neemt en met $sort wordt samengevoegd tot een efficiënte top-N-sortering, en dat $skip paginering met een verschuivingswaarde implementeert maar trager wordt bij diepe verschuivingswaarden. Vervolgens bekijken we geavanceerde aggregatiefasen, waaronder $lookup voor het koppelen van verzamelingen.
Leer JavaScript met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 30
- Lessen
- 120
Veelgestelde vragen
Is de les “$sort, $limit en $skip in de pipeline” gratis?
Ja — de volledige tekst van “$sort, $limit en $skip in de pipeline” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus MongoDB Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus MongoDB Academy bevat in totaal 4 lessen.
Wat leer ik in “$sort, $limit en $skip in de pipeline”?
U ordent en pagineert aggregatieresultaten en begrijpt de optimalisatieregels voor het vóór $group plaatsen van $match en $sort. Je oefent met MongoDB Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met MongoDB Academy te beginnen?
Ervaring vooraf is niet nodig. MongoDB Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.
Hoe lang duurt de les “$sort, $limit en $skip in de pipeline”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over MongoDB Academy?
Ja. Elke les over MongoDB Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Pipelineconcepten: fasen, operators en expressies
- $match en $project: filteren en hervormen
- $group: totalen aggregeren en berekenen
- $sort, $limit en $skip in de pipeline