获取所有文档数组中的总金额

时间:2017-04-22 14:22:44

标签: mongodb mongodb-query aggregation-framework

我在用户集合中的文档如下所示:

{
    "_id" : ObjectId("58ca3a856d13601f9a474dca"),
    "name" : "user A",
    "email" : "userA@gmail.com",
    "transaction" : [ 
        {
            "amount" : 50,
            "type" : "CASH"
        }
    ]
},

{
    "_id" : ObjectId("58ca3a856d13601f9a474dcb"),
    "name" : "user B",
    "email" : "userB@gmail.com",
    "transaction" : [ 
        {
            "amount" : 100,
            "type" : "CHEQUE"
        },
        {
            "amount" : 200,
            "type" : "CASH"
        },
        {
            "amount" : -20,
            "type" : "USED_SERVICE"
        }
    ]
},

{
    "_id" : ObjectId("58ca3a856d13601f9a474dcc"),
    "name" : "user C",
    "email" : "userC@gmail.com",
    "transaction" : [ 
        {
            "amount" : 20,
            "type" : "CASH"
        },
        {
            "amount" : -5,
            "type" : "USED_SERVICE"
        }        
    ]
}

我需要将所有用户的所有交易加起来,如CASH或CHECK。

我尝试了$ sum聚合运算符,但仍然不知道如何使它运行。

https://docs.mongodb.com/manual/reference/operator/aggregation/sum/

3 个答案:

答案 0 :(得分:2)

db.user.aggregate(
    {$unwind: "$transaction"},
    {$match: {"transaction.type": {$in: ["CASH", "CHEQUE"]}}},
    {$group: {_id: "total", sum: {$sum: "$transaction.amount"}}}
)
  1. 第一个unwind交易数组
  2. 然后,match按交易类型
  3. 最后,group所有交易,总结其金额

答案 1 :(得分:0)

根据上述描述作为解决方案,请尝试在MongoDB shell中执行以下查询

db.user.aggregate(

  // Pipeline
  [
    // Stage 1
    {
      $match: {
      transaction:{$elemMatch:{type:{$in:['CHEQUE','CASH']}}}
      }
    },

    // Stage 2
    {
      $unwind: {path:'$transaction'}
    },

    // Stage 3
    {
      $group: {
       _id:{type:'$transaction.type'},
       total:{$sum:'$transaction.amount'}
      }
    }

  ]


);

答案 2 :(得分:-1)

实现此目的的最佳方式实际上是MongoDB 3.4或更高版本。 此版本的mongod提供$reduce运算符,允许我们将$sum运算符应用于“amount”值的数组,其中“type”为“CASH”或“CHECK”。

但首先您需要通过$filter“transaction”数组计算该数组,并使用$map数组运算符仅返回“amount”值。

$filter中的“cond”表达式是一个简单的$in表达式,也是版本3.4中的新表达式。

当然要获取集合中所有文档的总数,您需要在$group阶段执行此操作并使用null或编程语言中的等效项{{1}价值。

_id

如果您的db.collection.aggregate([ { "$group": { "_id": null, "total": { "$sum": { "$reduce": { "input": { "$map": { "input": { "$filter": { "input": "$transaction", "as": "t", "cond": { "$in": [ "$$t.type", [ "CASH", "CHEQUE" ] ] } } }, "as": "elt", "in": "$$elt.amount" } }, "initialValue": 0, "in": { "$add": [ "$$value", "$$this" ] } } } } } } ]) 版本为3.2,则另一种效率较低的替代方法是使用“cond”表达式中的$setIsSubset运算符mongod“事务”数组。

从那里,您计算另一个$filter阶段中“金额”值的总和,并在最终$project阶段返回包含$sum的所有文档的总和。

$group