获取MongoDB中的值的总和

时间:2014-04-16 03:23:19

标签: node.js mongodb aggregation-framework

我有一个数组,该数组中的每个列表项都是一个具有值键的对象。我想要做的是添加所有值以获得总计。我想在后端而不是前端做到这一点。我已经尝试了聚合方法,但没有运气,因为它返回一个空数组。这是我的阵列:

"budgets" : [
    {
        "name" : "check",
        "value" : "1000",
        "expense" : "false",
        "uniqueId" : 0.9880268634296954
    },
    {
        "name" : "car",
        "value" : "500",
        "expense" : "true",
        "uniqueId" : 0.1904486275743693
    },
    {
        "name" : "car2",
        "value" : "500",
        "expense" : "false",
        "uniqueId" : 0.23043920518830419
    },
    {
        "name" : "car23",
        "value" : "500",
        "expense" : "false",
        "uniqueId" : 0.014449386158958077
    },
    {
        "name" : "car235",
        "value" : "500",
        "expense" : "false",
        "uniqueId" : 0.831609656335786
    }
],

我想要做的是获得具有"费用"的值的总和。 :" true"并得到一个单独的"费用" :" false"我该怎么做?就像我说我已经尝试了聚合方法,但我必须做错了。

3 个答案:

答案 0 :(得分:2)

如果您不熟悉使用聚合框架命令,则可能还不了解$cond运算符。您可以使用它来分隔总计:

db.collection.aggregate([

    // Unwind the array to de-normalize the items
    { "$unwind": "$budgets" },

    // Group the totals with conditions
    { "$group": {
        "_id": "$_id",
        "expense": { "$sum": { 
            "$cond": [
                "$budgets.expense",
                "$budgets.value",
                0
            ]
        }},
        "nonExpense": { "$sum": { 
            "$cond": [
                "$budgets.expense",
                0,
                "$budgets.value"
            ]
        }}

    }}

])

那么将要做的是将费用的true/false条件作为第一个参数进行评估,当条件实际为true时,将选择$cond的第二个参数,传递给 $sum 。如果条件求值为false,则选择第二个参数。

但是看看你的数据,你似乎遇到了问题:

    {
        "name" : "check",
        "value" : "1000",
        "expense" : "false",
        "uniqueId" : 0.9880268634296954
    },

请注意,所有字段,尤其是expensevalue项都是字符串。所以这是一个问题,因为虽然我们可以通过字符串比较而不是直接布尔值来评估true/false值,但您根本无法将字符串作为可以传递给$sum的数字。

首先,您需要修复您的数据,除非它实际上不在您所代表的表单中。但是当它遇到正确的形式时,你可以进行聚合。

答案 1 :(得分:1)

首先将值的数据类型从字符串转换为整数(可汇总)类型,然后使用

db.collectioName.aggregate(
    {$unwind:"$budgets"},

    {
    $group:{_id: "$budgets.expense",
    total: { $sum: "$budgets.value"}}
    })

然后你应该得到这样的结果

{
    "result" : [
        {
            "_id" : "true",
            "total" : 500
        },
        {
            "_id" : "false",
            "total" : 2000
        }
    ],
    "ok" : 1
}

答案 2 :(得分:0)

尝试这样的事情

db.collection.aggregate([ { "$unwind": "$budgets" },
                  { $match: { expense: "true" } },
                  { $group: { _id: "$_id",
                            name: { $addToSet: "$name" },
                            uniqueId: { $addToSet: "$uniqueId" }, 
                            total: { $sum: "$$budgets.value" } } }
               ])