在MongoDB中

时间:2016-01-01 12:57:36

标签: mongodb mongodb-query aggregation-framework

我正在尝试在MongoDB中进行聚合。

我有一些收藏品。每个项目都有一个数组rowsrows中的每个对象都有字段quantityprice

我希望将quantityprice相乘,但我不知道如何正确指定字段。

我试过了

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
    },
  ]
}

1 个答案:

答案 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" } 
    }}
])