MongoDB: How to merge all documents into a single document in an aggregation pipeline

Viewed 250

I have the current aggregation output as follows:

[
    {
        "courseCount": 14
    },
    {
        "registeredStudentsCount": 1
    }
]

The array has two documents. I would like to combine all the documents into a single document having all the fields in mongoDB

2 Answers
 db.collection.aggregate([
 {
   $group: {
    _id: 0,
     merged: {
    $push: "$$ROOT"
   }
   }
  },
 {
  $replaceRoot: {
  newRoot: {
    "$mergeObjects": "$merged"
   }
  }
 }
])

Explained:

  1. Group the output documents in one field with push
  2. Replace the document root with the merged objects

Plyaground

{
    $group: {
      "_id": "null",
      data: {
        $push: "$$ROOT"
      }
    }
  }

When you add this as the last pipeline, it will put all the docs under data, but here data would be an array of objects.

In your case it would be

{ "data":[
    {
        "courseCount": 14
    },
    {
        "registeredStudentsCount": 1
    }
] }

Another approach would be,

db.collection.aggregate([
  {
    $group: {
      "_id": "null",
      f: {
        $first: "$$ROOT",
        
      },
      l: {
        $last: "$$ROOT"
      }
    }
  },
  {
    "$project": {
      "output": {
        "courseCount": "$f.courseCount",
        "registeredStudentsCount": "$l.registeredStudentsCount"
      },
      "_id": 0
    }
  }
])

It's not dynamic as first one. As you have two docs, you can use this approach. It outputs

[
  {
    "output": {
      "courseCount": 14,
      "registeredStudentsCount": 1
    }
  }
]

With extra pipeline in the second approach

 {
    "$replaceRoot": {
      "newRoot": "$output"
    }
  }

You will get the output as

[
  {
    "courseCount": 14,
    "registeredStudentsCount": 1
  }
]
Related