mongo $项目没有预测原始价值

时间:2017-04-23 11:52:12

标签: mongodb aggregation-framework

我是Mongodb和NoSQL的新手,我正在尝试使用mongodbs聚合函数来聚合来自一个集合的数据以插入到另一个集合中。原始集合的一个例子是:

原创收藏品 { supplier: 'aldi', timestamp: '1492807458', user: 'eddardstark@gmail.com', hasBeenAggregated:false, items:[{ name: 'butter', supplier: 'aldi', expiry: '1492807458', amount: 454, measureSymbol: 'g', cost: 2.19 },{ name: 'milk', supplier: 'aldi', expiry: '1492807458', amount: 2000, measureSymbol: 'ml', cost: 1.49 }] }

我想要实现的输出的一个例子是:

新收藏 { user:'eddardstark@gmail.com', amount: 3.68, isIncome: false, title: 'food_shopping', timestamp: '1492807458' }

我使用的聚合函数是:

聚合 var result = db.runCommand({ aggregate: 'food_transactions', pipeline: [ {$match: {hasBeenAggregated: false}}, {$unwind: '$items'}, {$group:{_id: '$_id',amount:{$sum: '$items.cost'}}}, {$project: { _id:0, user:1, amount:1, isIncome: {$literal: false}, title:{$literal: 'food_shopping'}, timestamp:1 }} ] }); printjson(result)

此聚合函数不会返回usertimestamp字段。相反,我得到以下输出:

输出 { "amount" : 3.6799999999999997, "isIncome" : false, "title" : "food_shopping" }

如果我没有对结果进行分组并在$project阶段执行计算,那么这些字段都会正确投影,但显然,为{{1}中的每个子文档创建了一个新文档数组,而不是失败聚合的目的。

我做错了什么?

1 个答案:

答案 0 :(得分:2)

更新您的$group管道,以包含您希望在管道中进一步投射的所有字段。

要包含用户字段,您可以使用$first

{$group:{_id: '$_id', user:{$first:'$user`}, amount:{$sum: '$items.cost'}}},

此外,如果你是3.4版本,你可以简化你的聚合到下面。

使用$reduce汇总单个文档中的所有item费用。对于所有文档,您可以在$group之后添加$reduce

db.collection.aggregate([
        {$match: {hasBeenAggregated: false}},
        {$project: {
            _id:0,
            user:1,
            amount: {
              $reduce: {
                input: "$items",
                initialValue: 0,
                in: { $add : ["$$value", "$$this.cost"] }
              }
            },
            isIncome: {$literal: false},
            title:{$literal: 'food_shopping'},
            timestamp:1
        }}
    ])