How can I aggregate nested documents in MongoDB?


To aggregate nested documents in MongoDB, you can use $group. Let us first create a collection with documents −
> db.aggregateDemo.insertOne(
...    {
...       "ProductInformation": [
...          {
...             "Product1": [
...                {
...                   Amount: 50
...                },
...                {
...                   Amount: 90
...                },
...                {
...                   Amount: 30
...                }
...             ]
...          },
...          {
...             "Product1": [
...                {
...                   Amount: 200
...                },
...                {
...                   Amount: 30
...                },
...                {
...                   Amount: 40
...                }
...             ]
...          },
...          {
...             "Product1": [
...                {
...                   Amount: 150
...                },
...                {
...                   Amount: 190
...                },
...                {
...                   Amount: 198
...                }
...             ]
...          }
...
...       ]
... });
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e04df58150ee0e76c06a04d")
}
> db.aggregateDemo.insertOne(
...    {
...       "ProductInformation": [
...          {
...             "Product1": [
...                {
...                   Amount: 100
...                },
...                {
...                   Amount: 1002
...                },
...                {
...                   Amount: 78
...                }
...             ]
...          },
...          {
...             "Product1": [
...                {
...                   Amount: 75
...                },
...                {
...                   Amount: 400
...                },
...                {
...                   Amount: 600
...                }
...             ]
...          },
...          {
...             "Product1": [
...                {
...                   Amount: 700
...                },
...                {
...                   Amount: 500
...                },
...                {
...                   Amount: 600
...                }
...             ]
...          }
...
...       ]
... });
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e04df93150ee0e76c06a04e")
}
Following is the query to display all documents from a collection with the help of find() method −
> db.aggregateDemo.find().pretty();
This will produce the following output −
{
   "_id" : ObjectId("5e04df58150ee0e76c06a04d"),
   "ProductInformation" : [
      {
         "Product1" : [
            {
               "Amount" : 50
            },
            {
               "Amount" : 90
            },
            {
               "Amount" : 30
            }
         ]
      },
      {
         "Product1" : [
      {
         "Amount" : 200
      },
      {
         "Amount" : 30
      },
      {
         "Amount" : 40
      }
   ]
},
{
   "Product1" : [
      {
         "Amount" : 150
      },
      {
         "Amount" : 190
      },
      {
         "Amount" : 198
      }
   ]
}
]
}
{
   "_id" : ObjectId("5e04df93150ee0e76c06a04e"),
   "ProductInformation" : [
      {
         "Product1" : [
            {
               "Amount" : 100
            },
            {
               "Amount" : 1002
            },
            {
               "Amount" : 78
            }
         ]
      },
   {
      "Product1" : [
         {
            "Amount" : 75
         },
         {
            "Amount" : 400
         },
         {
            "Amount" : 600
         }
      ]
   },
   {
      "Product1" : [
         {
            "Amount" : 700
         },
         {
            "Amount" : 500
         },
         {
            "Amount" : 600
         }
      ]
   }
]
}
Here is the query to aggregate nested documents −
> db.aggregateDemo.aggregate([
... {
...    $unwind:"$ProductInformation"
... },
... {
...    $unwind:"$ProductInformation.Product1"
... },
... {
...    $group:{
...       _id:null,
...       MaximumAmount:{
...          $max:"$ProductInformation.Product1.Amount"
...       }
...    }
... }
... ]);
This will produce the following output −
{ "_id" : null, "MaximumAmount" : 1002 }