Search code examples
mongodbaggregation-frameworknosql-aggregation

How to aggregate array value objects by key in MongoDB


Given the following collection

{ "_id": 1, "items": [ { "k": "A", "v": 1 }, { "k": "B", "v": 2 } ] }
{ "_id": 2, "items": [ { "k": "A", "v": 3 }, { "k": "B", "v": 4 } ] }

How can I sum all the items having the same key k, preserving the original object format like so:

{ "items": [ { "k": "A", "v": 4 }, { "k": "B", "v": 6 } ] }

I tried using $unwind and $group, but it returns a sequence of objects instead of single item.

{ $unwind: { path: "$items" } },
{
  $group: {
    _id: "$items.k",
    v: { $sum: "$items.v" }
  }
}

I could aggregate it back into the original format, but I feel there must be a better way to do it.


Solution

    • $unwind deconstruct items array
    • $group by items.k and get sum of v
    • $group by null and reconstruct items array
    db.collection.aggregate([
      { $unwind: "$items" },
      {
        $group: {
          _id: "$items.k",
          v: { $sum: "$items.v" }
        }
      },
      {
        $group: {
          _id: null,
          items: {
            $push: {
              k: "$_id",
              v: "$v"
            }
          }
        }
      }
    ])
    

    Playground