intermediate
Aggregation pipeline
Используйте pipeline stages для filter, reshape, group, join и compute data без переноса всей работы в application code.
Aggregation pipeline обрабатывает документы через упорядоченные stages — серверный dataflow. Используйте его для filter, reshape, group, join и вычислений рядом с данными, а не для передачи огромных наборов в приложение.
db.orders.aggregate([
{ $match: { status: "paid", createdAt: { $gte: ISODate("2026-06-01") } } },
{ $unwind: "$items" },
{ $group: {
_id: "$items.sku",
revenue: { $sum: { $multiply: ["$items.qty", "$items.price"] } },
orders: { $addToSet: "$_id" }
}},
{ $project: { sku: "$_id", revenue: 1, orderCount: { $size: "$orders" } } },
{ $sort: { revenue: -1 } },
{ $limit: 10 }
])
| Stage | Роль | |-------|------| | `$match` | Ранняя фильтрация; должен использовать индексы | | `$group` / `$bucket` | Агрегации и гистограммы | | `$lookup` | Left-outer join с другой коллекцией | | `$facet` | Несколько под-пайплайнов за один round trip | | `$set` / `$project` | Формирование выходных полей |
Ранние `$match` и `$sort` уменьшают working set. `$lookup` мощен, но дорог на масштабе — предпочитайте embedding или предварительную агрегацию. Есть лимиты памяти, если не включён `allowDiskUse`.
На интервью: набросайте stages для отчётного вопроса и укажите, где индексы должны обслуживать `$match`.
Типовые ошибки: `$lookup` по неиндексированным foreign fields; `$unwind`, взрывающий cardinality до `$group`; aggregation без `explain`; фильтрация в приложении после выборки слишком многих docs.
Компромисс — серверные вычисления и сложность pipeline vs сеть и память приложения: pipeline выигрывает, когда убирает большие передачи и дублирование бизнес-логики.
Чеклист:
- Ставьте селективный `$match` первым.
- Назовите stages для filter, join, group и project.
- Проверьте индексы на полях match.
- Оцените cardinality после `$unwind` и `$lookup`.