Group and push objects in array if they having same key in mongodb document

Viewed 172

I am working on MongoDb aggregation. I am new for mongo pipelines and stuck on some point. I have documents in MongoDB collection like below. I am unable to guess how to move forward to get expected result:

{
    resource: {
        name: "PROJECT_01", 
        version: 1,
        owner: ""
        },
    app_info: [
        {
        app_key: "APP_01",
        size: 20,
        metadata:{
            deploy_on: "AWS",
            status: "running",
            reason:{}
            }
        },
        {
        app_key: "APP_01",
        size: 20,
        metadata:{
            deploy_on: "azure",
            status: "failed",
            reason:{
                message: "Connectivity Issue",
                error_code: "CONNECTIVITY_ERROR"
                }
            }
        },
        {
        app_key: "APP_02",
        size: 20,
        metadata:{
            deploy_on: "AWS",
            status: "running",
            reason:{}
            }
        },
        {
        app_key: "APP_02",
        size: 20,
        metadata:{
            deploy_on: "azure",
            status: "failed",
            reason:{
                message: "Connectivity Issue",
                error_code: "CONNECTIVITY_ERROR"
                }
            }
        },
    ]
}

I want to combine metadata on bases of "app_key" by using aggregation and expected output should be like this:

{
    resource: {
        name: "PROJECT_01", 
        version: 1,
        owner: ""
        },
    app_info: [
        {
        app_key: "APP_01",
        size: 20,
        metadata:[{
            deploy_on: "AWS",
            status: "running",
            reason:{}
            },
            {
            deploy_on: "azure",
            status: "failed",
            reason:{
                message: "Connectivity Issue",
                error_code: "CONNECTIVITY_ERROR",
                }
            }
        ]},
        {
        app_key: "APP_02",
        size: 20,
        metadata:[{
            deploy_on: "AWS",
            status: "running",
            reason:{}
            },
            {
            deploy_on: "azure",
            status: "failed",
            reason:{
                message: "Connectivity Issue",
                error_code: "CONNECTIVITY_ERROR"
                }
            }
        ]}
}

If someone have idea, Please share here. Thanks.

1 Answers

Welcome to mongo db, You can try something like following.

  • $unwind to deconstruct the array
  • $group to reconstruct the array for the expected format. $first helps to get the first element of the documents. $addToSet helps to remove if there any duplicates while phusing into an array. You can use $push
  • $addFields to get the expected format.

Script is..

db.collection.aggregate([
  {
    $unwind: "$app_info"
  },
  {
    $group: {
      _id: {
        app_key: "$app_info.app_key",
        resource: "$resource"
      },
      size: {
        $first: "$app_info.size"
      },
      metadata: {
        $push: "$app_info.metadata"
      },
      resource: {
        $first: "$resource"
      }
    }
  },
  {
    $group: {
      _id: "$_id.resource",
      appInfos: {
        $push: {
          app_key: "$_id.app_key",
          size: "$size",
          metadata: "$metadata"
        }
      }
    }
  }
])

Working Mongo playground

Related