用于算术运算的 MongoDB 聚合 - 子文档字段

Posted

技术标签:

【中文标题】用于算术运算的 MongoDB 聚合 - 子文档字段【英文标题】:MongoDB aggregate for Arithmetic Operations - Subdocument Field 【发布时间】: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 已更新文档和预期输出 感谢您的更新,我已经更新了下面的答案以合并更改。 【参考方案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 好的,我已经使用考虑到所需输出的正确聚合管道更新了我的答案。

以上是关于用于算术运算的 MongoDB 聚合 - 子文档字段的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB/Mongoose - 与 geoNear 和子文档的聚合

使用聚合 mongodb mongoose 将集合子子文档与其他集合子文档连接起来

mongodb基础整理篇————聚合操作[三]

在 Mongodb 中查找和聚合多个级别的子文档

如何使用 MongoDB 聚合管道从集合中的两个子文档中返回最小值?

20180806