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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.