Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB: aggregate grouping objects in array inside of an array of objects

I need to group the objects inside of votes by mallId inside of a mongodb aggreate pipeline. Been searching for an answer for ages, but I am not too familiar with mongodb so I am kind of lost. Can anyone help me out?

     [
      {
        "_id": "Specialty Retailer",
        "votes": [
          {
            "mallId": "59ddea3718a03a4e81f289f5",
            "count": 13
          },
          {
            "mallId": "59ddea3718a03a4e81f289f5",
            "count": 270
          },
          {
            "mallId": "59ddea3718a03a4e81f289f5",
            "count": 13
          },
          {
            "mallId": "59ddea3718a03a4e81f289f5",
            "count": 2
          },
          {
            "mallId": "59ddea3718a03a4e81f289f5",
            "count": 15
          },
          {
            "mallId": "59ddea3718a03a4e81f289f5",
            "count": 2
          }
     ]
   }
]
like image 613
Ryan M Avatar asked Nov 07 '17 16:11

Ryan M


People also ask

What is an accumulator object MongoDB?

Accumulators are operators that maintain their state (e.g. totals, maximums, minimums, and related data) as documents progress through the pipeline. Use the $accumulator operator to execute your own JavaScript functions to implement behavior not supported by the MongoDB Query Language.

What is $$ root in MongoDB?

The $$ROOT variable contains the source documents for the group. If you'd like to just pass them through unmodified, you can do this by $pushing $$ROOT into the output from the group.

What is $first in MongoDB?

This means $first returns the first order type for the documents between the beginning of the partition and the current document.

Can we store array of objects in MongoDB?

One of the benefits of MongoDB's rich schema model is the ability to store arrays as document field values. Storing arrays as field values allows you to model one-to-many or many-to-many relationships in a single document, instead of across separate collections as you might in a relational database.


1 Answers

Given the following document structure

{
    "_id" : ObjectId("5a020ea06216d24dd6050a07"),
    "arr" : [ 
        {
            "_id" : "Specialty Retailer",
            "votes" : [ 
                {
                    "mallId" : "59ddea3718a03a4e81f289f5",
                    "count" : 13
                }, 
                {
                    "mallId" : "59ddea3718a03a4e81f289f5",
                    "count" : 270
                }
            ]
        }
    ]
}

this query should get you going:

db.collection.aggregate({
    $unwind: "$arr"
}, {
    $unwind: "$arr.votes"
}, {
    $group: {
        "_id": {
            "_id": "$_id",
            "arrId": "$arr._id",
            "mallId": "$arr.votes.mallId"
        },
        "totalCount": {
            $sum: "$arr.votes.count"
        }
    }
})
like image 60
dnickless Avatar answered Oct 25 '22 11:10

dnickless