Группировать несколько раз в рамках агрегации, сохраняя несколько полей

#mongodb #aggregation-framework

#mongodb #структура агрегации

Вопрос:

Мне нужно несколько раз группировать коллекцию, содержащую несколько полей. Я пробовал $group в рамках агрегации, но, вероятно, я совершаю ошибку, потому что не могу сохранить разные поля, которые мне нужны.

Вот пример:

 [
  {
    "courseTitle": "Master 1",
    "courseCompleted": false,
    "module_id": "m01",
    "section": "01 - Introduction",
    "order": 1,
    "completed": true,
    "moduleTitle": "Module 1"
  },
  {
    "courseTitle": "Master 1",
    "courseCompleted": false,
    "module_id": "m02",
    "section": "01 - Introduction",
    "order": 2,
    "completed": true,
    "moduleTitle": "Module 2"
  },
  {
    "courseTitle": "Master 1",
    "courseCompleted": false,
    "module_id": "m03",
    "section": "01 - Introduction",
    "order": 3,
    "completed": false,
    "moduleTitle": "Module 3"
  },
  {
    "courseTitle": "Master 1",
    "courseCompleted": false,
    "module_id": "m04",
    "section": "02 - First test",
    "order": 4,
    "completed": false,
    "moduleTitle": "Module 4"
  }
]
  

Мне нужно сначала сгруппировать по разделам, а затем по courseTitle courseCompleted полям И:

 [
  {
    "courseTitle": "Master 1",
    "courseCompleted": false,
    "sections": [
      {
        "section": "01 - Introduction",
        "modules": [
          {
            "module_id": "m01",
            "order": 1,
            "completed": true,
            "moduleTitle": "Module 1"
          },
          {
            "module_id": "m02",
            "order": 2,
            "completed": true,
            "moduleTitle": "Module 2"
          },
          {
            "module_id": "m03",
            "order": 3,
            "completed": false,
            "moduleTitle": "Module 3"
          },     
        ]
      },
      {
        "section": "02 - First test",
        "modules": [
          {
            "module_id": "m04",
            "order": 4,
            "completed": false,
            "moduleTitle": "Module 4"
          }
        ]
      }
    ]
  }
]
  

Пример на игровой площадке: https://mongoplayground.net/p/ThqXLYmQTCe

Ответ №1:

Вам нужно запустить $group, чтобы получить вложенный массив:

 db.collection.aggregate([
    {
        $group: {
            _id: { courseTitle: "$courseTitle",  section: "$section", courseCompleted: "$courseCompleted" },
            modules: { $push: { module_id: "$module_id", order: "$order", completed: "$completed", moduleTitle: "$moduleTitle" } }
        }
    },
    { $sort: { "_id.section": 1 } },
    {
        $group: {
            _id: { courseCompleted: "$_id.courseCompleted", courseTitle: "$_id.courseTitle" },
            sections: { $push: { section: "$_id.section", modules: "$modules" } }
        }
    },
    {
        $project: {
            _id: 0,
            courseTitle: "$_id.courseTitle",
            courseCompleted: "$_id.courseCompleted",
            sections: 1
        }
    }
])
  

Игровая площадка Mongo