crivella
crivella

Reputation: 684

Group multiple times in aggregation framework keeping multiple fields

I need to group multiple time a collection keeping multiple fields. I've tried $group in aggregation framework but I probably make a mistake because I can't keep the different fields I need.

Here is the example:

[
  {
    "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"
  }
]

I need to group first by section and then by courseTitle AND courseCompleted fields:

[
  {
    "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"
          }
        ]
      }
    ]
  }
]

Example in playground: https://mongoplayground.net/p/ThqXLYmQTCe

Upvotes: 1

Views: 86

Answers (1)

mickl
mickl

Reputation: 49945

You need to run $group in order to get nested array:

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 Playground

Upvotes: 1

Related Questions