在MongoDB中对聚合中的嵌套字段使用$ multiply

Jam*_*een 4 mongodb mongodb-query aggregation-framework

我想在MongoDB中聚合.

我有一些收藏品.每个项目都有一个数组rows,每个对象rows都有字段quantityprice.

我想乘quantityprice,但我不知道如何正确指定的字段.

我试过了

const pipeline = [
  {
    $group: {
      _id: {
        number: '$number',
      },
      total: {
        $sum: {
          $multiply: [
            '$rows.quantity',
            '$rows.price'
          ]
        }
      },
    }
  }
];
Run Code Online (Sandbox Code Playgroud)

但它表示$multiply只支持数字类型而不支持数组.

所以它似乎不明白这$rows.quantityquantity数组中每个对象的数字类型字段.

我想我应该使用$each或其他东西来迭代数组中的对象.

使用乘法聚合与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
    },
  ]
}
Run Code Online (Sandbox Code Playgroud)

sty*_*ane 6

使用.aggregate()方法.

从版本3.2开始,您可以使用阶段中的$sum累加器运算符$project来计算并返回数组的总和quantity * price.当然要获得阵列,您需要使用$map运算符.该$ifNull运算符计算"量"和"价"的值,然后返回0,如果他们评价为空值.管道中的最后一个阶段是$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" } 
    }}
])
Run Code Online (Sandbox Code Playgroud)

如果您不是3.2版,则需要$project使用$unwind运算符在阶段之前对"rows"数组进行非规范化.

db.collection.aggregate([
    { "$unwind": "$rows" }, 
    { "$project": { 
        "number": 1,  
        "value": { "$multiply": [
            { "$ifNull": [ "$rows.quantity", 0 ] }, 
            { "$ifNull": [ "$rows.price", 0 ] } 
        ]}
    }}, 
    { "$group": { 
        "_id": "$number", 
        "total": { "$sum": "$value" } 
    }}
])
Run Code Online (Sandbox Code Playgroud)