9

MongoDb version 3.4.4

How to aggregate a new key 'total', whose value is the product of 'course' and 'quantity' for each object inside array snapshot.

Sample document:

{
    cur: "EUR",
    snapshot: [
        {
            id: "24352345",
            course: 58.12,
            quantity: 13
        },    
        {
            id: "34552345",
            course: 18.12,
            quantity: 63
        }
    ]
}

Desired result:

{
    cur: "EUR",
    snapshot: [
        {
            id: "24352345",
            course: 58.12,
            quantity: 13,
            total: 755.56
        },    
        {
            id: "34552345",
            course: 18.12,
            quantity: 63,
            total: 1141.56
        }
    ]
}

first attempt:

db.mycoll.aggregate([{
    $addFields: {
        "snapshot.total": {
            $multiply:["$snapshot.quantity", "$snapshot.course"]
        }
    }
}])

"errmsg" : "$multiply only supports numeric types, not array"

Second attempt:

db.mycoll.aggregate( [ 
    { "$addFields": { 
        "snapshot.total": {
            "$map": { 
                "input": "$snapshot", 
                "as": "row", 
                "in": { "$multiply": [ 
                    { "$ifNull": [ "$$row.quantity", 0 ] }, 
                    { "$ifNull": [ "$$row.course", 0 ] } 
                ]} 
            }
        } 
    }} 
])

The undesired value of 'total' is an array with the totals of all the objects:

{
    cur: "EUR",
    snapshot: [
        {
            id: "24352345",
            course: 58.12,
            quantity: 13,
            total: [
                755.56,
                1141.56
            ]
        },    
        {
            id: "34552345",
            course: 18.12,
            quantity: 63,
            total: [
                755.56,
                1141.56
            ]
        }
    ]
}

1 Answer 1

16

Modify your second attempt using the $map operator to map the whole snapshot embedded document with its fields as

db.mycoll.aggregate([
    {
        "$addFields": {
            "snapshot": {
                "$map": {
                    "input": "$snapshot",
                    "as": "row",
                    "in": {
                        "id": "$$row.id",
                        "course": "$$row.course",
                        "quantity": "$$row.quantity",
                        "total": { "$multiply": [ 
                            { "$ifNull": [ "$$row.quantity", 0 ] }, 
                            { "$ifNull": [ "$$row.course", 0 ] } 
                        ]} 
                    }
                }
            }
        }
    }
])
Sign up to request clarification or add additional context in comments.

1 Comment

i have an array of object. In each object there is count field that i want to multiply and then set the multiplied value as total as the new document field.

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.