我正在尝试在MongoDB中进行聚合。
我有一些收藏品。每个项目都有一个数组rows
,rows
中的每个对象都有字段quantity
和price
。
我希望将quantity
和price
相乘,但我不知道如何正确指定字段。
我试过了
const pipeline = [
{
$group: {
_id: {
number: '$number',
},
total: {
$sum: {
$multiply: [
'$rows.quantity',
'$rows.price'
]
}
},
}
}
];
但是它说$multiply
只支持数字类型而不支持数组。
所以它似乎不理解$rows.quantity
是数组中每个对象中的数字类型字段quantity
。
我想我应该使用$each
或其他东西来迭代数组中的对象。
从Using multiply aggregation with MongoDB我看到我正确指定字段;但是,在该示例中,它是嵌套对象而不是数组,所以也许我必须使用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
},
]
}
答案 0 :(得分:6)
使用.aggregate()
方法。
从版本3.2开始,您可以使用$sum
阶段中的$project
累加器运算符来计算并返回quantity * price
数组的总和。当然要获得阵列,您需要使用$map
运算符。 $ifNull
运算符评估"数量"的值。和"价格"然后如果它们评估为空值,则返回0
。管道中的最后一个阶段是$group
阶段,您可以通过" number"并返回"总计"每个小组。
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" }
}}
])
如果您不在3.2版本上,则需要对#34;行进行非规范化。使用$unwind
运算符在$project
阶段之前的数组。
db.collection.aggregate([
{ "$unwind": "$rows" },
{ "$project": {
"number": 1,
"value": { "$multiply": [
{ "$ifNull": [ "$rows.quantity", 0 ] },
{ "$ifNull": [ "$rows.price", 0 ] }
]}
}},
{ "$group": {
"_id": "$number",
"total": { "$sum": "$value" }
}}
])