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`.