【问题标题】:MongoDB aggregate for Arithmetic Operations - Subdocument Field用于算术运算的 MongoDB 聚合 - 子文档字段
【发布时间】:2015-07-14 00:04:24
【问题描述】:

我们有一个聚合查询投射几个子文档。我们想对这些投影值应用一些算术运算,例如 Sum 和 Product。

聚合查询 --

Item.aggregate([
        { $unwind: '$dummy'},       
        { $match: {'dummy.storage': {$gt: 0}} },
        { $group: {_id: '$_id',
                    dummy: {$push: '$dummy'},
                    original_y: { $first: "$original_y" },
                    new_y: { $first: "$new_y" },

        }},
        {$project:{
                  original_y: 1, new_y: 1,
                  tallyAmount: {$sum: ["$new_y","$original_y"] }
                }
        },
     ]
    )
    .exec(function(err, results){   
        if(err)
        {
            console.log("Error : " + err);
            return res.json ({error: "Error"});

        }
        else if(!(results) || results == null || results.length == 0)
        {
            console.log("No Results Found");
            return res.json ({error: "No Results Today"});

        }else{

            res.send(results);
        }
    });

这给出了一个错误说明 invalid operator '$sum'

我们应该怎么做才能得到$projectoriginal_ynew_y的总和?

编辑

文件:

{
 id:1,
 original_y: 200,
 new_y: 140,
 dummy: [
  {id:1, storage:2, cost: 10},
  {id:2, storage:0, cost: 20},
  {id:3, storage:5, cost: 30},
  ]
}

预期输出:

 {
     id:1,
     original_y: 200,
     new_y: 140,
     dummy: [
      {id:1, storage:2, cost: 10, tallyAmount: 34},
      {id:3, storage:5, cost: 30, tallyAmount: 11.33},
      ]
    }

在哪里, tallyAmount = (original_y + new_y) / cost

错误:无法为 dummy 的子字段添加表达式,因为已经存在适用于整个字段的表达式

【问题讨论】:

  • @chridam 已更新文档和预期输出
  • 感谢您的更新,我已经更新了下面的答案以合并更改。

标签: node.js mongodb mongoose aggregation-framework


【解决方案1】:

如果没有您的文档架构和预期聚合结果的详细信息,我建议您尝试以下聚合,因为我认为您需要 $add 运算符而不是 $sum 运算符。请注意,$sum 运算符仅适用于 $group 运算符。使用$add 运算符,它将两个数字/字段加在一起,结果存储在使用$project 运算符的新字段中:

Item.aggregate([
    { "$match": { "dummy.storage": { "$gt": 0 } } },
    { "$unwind": "$dummy" },   
    { "$group": { 
        "_id": "$_id", 
        "original_y": { "$first": "$original_y" },
        "new_y": { "$first": "$new_y" }
    } },
    { "$project": {
        "original_y": 1, 
        "new_y": 1,
        "tallyAmount": { "$add": [ "$new_y", "$original_y" ] }
    } }
]).exec(callback);

-- 更新--

要满足条件 tallyAmount = (original_y + new_y) / cost,您应该在 $project 运算符管道阶段使用 $add$divide 算术运算符,因此您的最终聚合管道将如下所示:

Item.aggregate([
    { "$match": { "dummy.storage": { "$gt": 0 } } },
    { "$unwind": "$dummy" },
    {
        "$project": {
            "original_y": 1, 
            "new_y": 1,
            "dummy.id": "$dummy.id",
            "dummy.storage": "$dummy.storage",
            "dummy.cost": "$dummy.cost",
            "dummy.tallyAmount": {
                "$divide": [
                    { "$add": ["$new_y","$original_y"] },
                    "$dummy.cost"
                ]
            }
        }
    },
    {
        "$group": {
            "_id": "_$id",
            "original_y": { "$first": "$original_y" },
            "new_y": { "$first": "$new_y" },
            "dummy": {
                "$addToSet": "$dummy"
            }
        }        
    }
 ]).exec(callback);

【讨论】:

  • 唯一的问题是“tallyAmount”字段需要在每个“虚拟”子文档内。我面临一个从未听说过的错误! ERROR: can't add an expression for a subfield of dummy because there is already an expression that applies to the whole field
  • @RohitLala 好的,我已经使用考虑到所需输出的正确聚合管道更新了我的答案。
猜你喜欢
  • 2020-12-03
  • 1970-01-01
  • 2019-04-06
  • 1970-01-01
  • 2023-02-11
  • 2013-09-01
  • 2012-12-04
  • 1970-01-01
相关资源
最近更新 更多