Как сделать двухуровневую агрегацию в запросе?

Двухуровневая агрегация в MongoDB представляет собой процесс, при котором данные группируются на двух уровнях. Это может быть полезным, когда необходимо провести более подробный анализ данных и получить агрегированную информацию сразу по двум полям.

Для реализации двухуровневой агрегации в MongoDB требуется использование оператора $group, который позволяет группировать данные по заданным полям. Для выполнения второго уровня агрегации, необходимо вложить внутренний оператор $group внутри первого оператора $group.

Приведу пример, чтобы лучше понять как это работает. Предположим, у нас есть коллекция orders, содержащая информацию о заказах:

{
  "_id" : ObjectId("6113c722d29bf4c9774b035d"),
  "category" : "Electronics",
  "product" : "TV",
  "quantity" : 1,
  "price" : 1000
}
{
  "_id" : ObjectId("6113c722d29bf4c9774b035e"),
  "category" : "Electronics",
  "product" : "Phone",
  "quantity" : 2,
  "price" : 500
}
{
  "_id" : ObjectId("6113c722d29bf4c9774b035f"),
  "category" : "Clothing",
  "product" : "Shirt",
  "quantity" : 3,
  "price" : 50
}
{
  "_id" : ObjectId("6113c722d29bf4c9774b0360"),
  "category" : "Clothing",
  "product" : "Pants",
  "quantity" : 1,
  "price" : 75
}

Чтобы выполнить двухуровневую агрегацию и получить сумму стоимости заказов для каждой категории и каждого продукта, можно использовать следующий запрос:

db.orders.aggregate([
  {
    $group: {
      _id: {
        category: "$category",
        product: "$product"
      },
      total: { $sum: { $multiply: [ "$quantity", "$price" ] } }
    }
  },
  {
    $group: {
      _id: "$_id.category",
      products: {
        $push: {
          product: "$_id.product",
          total: "$total"
        }
      }
    }
  }
])

Результатом данного запроса будет следующий вывод:

[
  {
    "_id": "Clothing",
    "products": [
      {
        "product": "Shirt",
        "total": 150
      },
      {
        "product": "Pants",
        "total": 75
      }
    ]
  },
  {
    "_id": "Electronics",
    "products": [
      {
        "product": "TV",
        "total": 1000
      },
      {
        "product": "Phone",
        "total": 1000
      }
    ]
  }
]

В данном выводе мы получаем общую стоимость заказов для каждой категории и список продуктов с их суммарной стоимостью внутри каждой категории.

Надеюсь, это помогло вам понять, как сделать двухуровневую агрегацию в MongoDB!