I am trying to aggregate in MongoDB.
I have a collection with some items. Each item has an array rows
and each object in rows
has fields quantity
and price
.
I want to multiply quantity
and price
, but I don't know how to specify the fields correctly.
I have tried
const pipeline = [
{
$group: {
_id: {
number: '$number',
},
total: {
$sum: {
$multiply: [
'$rows.quantity',
'$rows.price'
]
}
},
}
}
];
but it says that $multiply
only supports numeric types and not arrays.
So it seems it doesn't understand that $rows.quantity
is the numeric type field quantity
in each object in the array.
I guess I should probably use $each
or something else in order to iterate through the objects in the array.
From Using multiply aggregation with MongoDB I see that I am specifying the fields correctly; however, in that example it is a nested object instead of an array, so maybe I have to use https://docs.mongodb.org/v3.0/reference/operator/aggregation/unwind/?
{
number: 2,
rows: [
{
quantity: 10,
price: 312
},
{
quantity: 10,
price: 312
},
{
quantity: 10,
price: 312
},
]
}
Using the .aggregate()
method.
Starting in version 3.2 you can use the $sum
accumulator operator in the $project
stage to calculates and returns the sum of array of quantity * price
. Of course to get the array you need to use the $map
operator. The $ifNull
operator evaluates the value of "quantity" and "price" then returns 0
if they evaluate to a null value. The last stage in the pipeline is the $group
stage where you group your document by "number" and return the "total" for each each group.
db.collection.aggregate([
{ "$project": {
"number": 1,
"total": {
"$sum": {
"$map": {
"input": "$rows",
"as": "row",
"in": { "$multiply": [
{ "$ifNull": [ "$$row.quantity", 0 ] },
{ "$ifNull": [ "$$row.price", 0 ] }
]}
}
}
}
}},
{ "$group": {
"_id": "$number",
"total": { "$sum": "$total" }
}}
])
If you are not on version 3.2 you will need to denormalize the "rows" array before the $project
stage using the $unwind
operator.
db.collection.aggregate([
{ "$unwind": "$rows" },
{ "$project": {
"number": 1,
"value": { "$multiply": [
{ "$ifNull": [ "$rows.quantity", 0 ] },
{ "$ifNull": [ "$rows.price", 0 ] }
]}
}},
{ "$group": {
"_id": "$number",
"total": { "$sum": "$value" }
}}
])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With