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

I have documents in mongo collection like this:

{
	resource: {
		name: "PROJ01", 
		version: 1,
		owner: ""
		},
	appInfos: [
		{
		app_key: "APP01",
		size: 20mb,
		metadata:{
			deployOn: "aws",
			status: "running",
			reason:{}
			}
		},
		{
		app_key: "APP01",
		size: 20mb,
		metadata:{
			deployOn: "azure",
			status: "failed",
			reason:{
				message: "Connectivity Issue",
				errorCode: "CONNECTIVITY_ERROR"
				}
			}
		},
		{
		app_key: "APP02",
		size: 20mb,
		metadata:{
			deployOn: "aws",
			status: "running",
			reason:{}
			}
		},
		{
		app_key: "APP02",
		size: 20mb,
		metadata:{
			deployOn: "azure",
			status: "failed",
			reason:{
				message: "Connectivity Issue",
				errorCode: "CONNECTIVITY_ERROR"
				}
			}
		},
	]
}

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

{
	resource: {
		name: "PROJ01", 
		version: 1,
		owner: ""
		},
	appInfos: [
		{
		app_key: "APP01",
		size: 20mb,
		metadata:[{
			deployOn: "aws",
			status: "running",
			reason:{}
			},
			{
			deployOn: "azure",
			status: "failed",
			reason:{
				message: "Connectivity Issue",
				errorCode: "CONNECTIVITY_ERROR"
				}
			}
		]},
		{
		app_key: "APP02",
		size: 20mb,
		metadata:[{
			deployOn: "aws",
			status: "running",
			reason:{}
			},
			{
			deployOn: "azure",
			status: "failed",
			reason:{
				message: "Connectivity Issue",
				errorCode: "CONNECTIVITY_ERROR"
				}
			}
		
		]}
}

Hello @Pradip_Kumar Welcome to MongoDB Developer Community,

You can use $unwind stage, Deconstructs an array field from the input documents to output a document for each element. Each output document is the input document with the value of the array field replaced by the element.
and $group stage, Groups input documents by the specified _id expression and for each distinct grouping, outputs a document. The _id field of each output document contains the unique group by value.

Your can design your query like, this is not tested, and my approach is you can do something like this for your expected result,

  • $unwind deconstruct appInfos array
  • $group by resource and app_key and construct the array of metadata
  • again $group by just resource and re-construct the appInfos array that we deconstructed in first stage.
  { $unwind: "$appInfos" },
  {
    $group: {
      _id: {
        app_key: "$appInfos.app_key",
        resource: "$resource"
      },
      size: { $first: "$appInfos.size" },
      metadata: { $push: "$appInfos.metadata" },
      resource: { $first: "$resource" }
    }
  },
  {
    $group: {
      _id: "$_id.resource",
      appInfos: {
        $push: {
          app_key: "$_id.app_key",
          size: "$size",
          metadata: "$metadata"
        }
      }
    }
  }

Hi @turivishal Thanks for quick reply. I’ll implement it and test it against my collection. Thanks again for solution.

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.