0

Is it possible to aggregate nested array element itself in Mongodb? e.g. the raw data is

{"transId" : "12345","customer" : "cust1", "product" : [{"type" : "cloth","price" : 100},{"type" : "toy","price" : 200}]}
{"transId" : "45672","customer" : "cust1", "product" : [{"type" : "cloth","price" : 10},{"type" : "toy","price" : 500}]}
{"transId" : "99999","customer" : "cust2", "product" : [{"type" : "cloth","price" : 40},{"type" : "toy","price" : 5}]}

I would like each of the nested array element is aggregated according to the type by customer e.g.

Result:

{"customer" : "cust1", "product" : [{"type" : "cloth","price" : 110},{"type" : "toy","price" : 700}]}
{"customer" : "cust2", "product" : [{"type" : "cloth","price" : 40},{"type" : "toy","price" : 5}]}

Could you please help to show me how to do that? Thanks.

1 Answer 1

2

You can do this using the aggregation framework. You need to denormalize the "product" array using $unwind operation. From there you need two $group stage. In the first group stage, you group your documents by _id which in your case must be a compound field, and use the $sum accumulator operator to return the sum of price. In the last $group stage you use the $push accumulator operator to return an array of "product".

db.customers.aggregate([ 
    // Denormalize the product array
    { "$unwind": "$product" }, 
    // Group your documents by `_id`
    { "$group": { 
        "_id": { "customer": "$customer", "type": "$product.type" }, 
        "price": { "$sum": "$product.price" } 
    }}, 
    // reconstruct the "product" array.
    { "$group": { 
        "_id": "$_id.customer", 
        "product": { "$push": { "type": "$_id.type", "price": "$price" } } 
    }}
])

Which returns:

{
        "_id" : "cust1",
        "product" : [
                {
                        "type" : "toy",
                        "price" : 700
                },
                {
                        "type" : "cloth",
                        "price" : 110
                }
        ]
}
{
        "_id" : "cust2",
        "product" : [
                {
                        "type" : "toy",
                        "price" : 5
                },
                {
                        "type" : "cloth",
                        "price" : 40
                }
        ]
}
Sign up to request clarification or add additional context in comments.

2 Comments

One addition. append {$project:{_id:0, customer:"$_id", product:1}} to aggregation pipeline to conform with OP desired format.
@Saleem No! adding $project will cause a drop of performance.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.