Optimize a pipeline
An aggregation that reads fewer documents and touches fewer ranges answers sooner.
Make an aggregation read fewer documents and touch fewer ranges. The router already sends each range the part of the pipeline it can do alone; you decide how much that part filters.
Requirements
- A connection with a user that has
readon the database.
Filter as early as possible
Put $match and $project at the start, on indexed fields. Those stages run on each range before results are merged.
Sort with a limit
A $sort followed by $limit becomes a top-k per range, which reads far less than sorting everything.
Look at the plan
JavaScript
db.orders.explain("executionStats").aggregate([{ $match: { status: "paid" } }, { $group: { _id: "$customer" } }]);Check
explain shows the ranges touched and how many documents each stage read; the numbers drop when you filter earlier.
Common problems
- A
$matchafter$groupcannot use indexes or run on each range; move it earlier if it filters fields of the documents.