如何计算Mongodb Aggregation中的字段

时间:2016-06-24 10:39:50

标签: mongodb aggregation-framework

我有一个包含这样的条目的文件

{ 
    "_id": ObjectId("5644c495d0807a1750043237"),
    "siteid": "123456"
    "amount": 1.32
}

某些文件有其他金额,例如"cashbackAmount"

我希望每个金额字段都有sumcount。并非每个文档都包含所有金额字段。

我hjave尝试了以下

{
    $group: {   
        "_id": "$siteid",
        item2: { "$sum": "$amount" },
        item3: { "$sum": "$totalAmount" },
        item4: { "$sum": "$cashbackAmount" },
        item5: { "$sum": "$unitPrice" },
    }
}  

它给了我总和,但我无法弄清楚如何获得每个数量字段的数量。

{ "$sum": 1 }不起作用,因为它为我提供了包含任何一个总计字段的所有文档。

2 个答案:

答案 0 :(得分:1)

如果您事先知道金额字段,那么您可以在一个动态创建管道的聚合操作中执行此操作。

查看以下演示:

var amountFields = ["amount", "totalAmount", "cashbackAmount", "unitPrice"],
    groupOperator = { "$group": { "_id": "$siteid" } };

amountFields.forEach(function (field){ 
    groupOperator["$group"][field+"Total"] = { "$sum": "$"+field }; 
    groupOperator["$group"][field+"Count"] = { 
       "$sum": {            
           "$cond": [ { "$gt": [ "$"+field, null ] }, 1, 0 ]
        }
    };
});

db.test.aggregate([groupOperator]);

填充测试文档

db.test.insert([
    { 
        "siteid": "123456",
        "amount": 1.32
    },
    { 
        "siteid": "123456",
        "cashbackAmount": 8.32
    },
    { 
        "siteid": "123456",
        "cashbackAmount": 9.74
    },
    { 
        "siteid": "123456",
        "unitPrice": 0.19
    },
    { 
        "siteid": "123456",
        "amount": 27.8,
        "totalAmount": 15.22,
        "unitPrice": 5.10,
        "cashbackAmount": 43.62    
    },
    { 
        "siteid": "123456",
        "unitPrice": 5.07
    },
    { 
        "siteid": "123456",
        "amount": 12.98,
        "totalAmount": 32.82
    },
    { 
        "siteid": "123456",
        "amount": 6.65,
        "unitPrice": 5.10
    }
])

样本汇总输出

{
    "_id" : "123456",
    "amountTotal" : 48.75,
    "amountCount" : 4,
    "totalAmountTotal" : 48.04,
    "totalAmountCount" : 2,
    "cashbackAmountTotal" : 61.68,
    "cashbackAmountCount" : 3,
    "unitPriceTotal" : 15.46,
    "unitPriceCount" : 4
}

答案 1 :(得分:1)

我猜你可能想要那样的东西

db.getCollection('amounts').aggregate([
    {
        $project: {
            siteid: 1,
            amount: 1,
            totalAmount: 1,
            unitPrice: 1,
            cashbackAmount: 1,
            amountPresent: {
                $cond: {
                    if: "$amount",
                    then: 1,
                    else: 0
                }
            },
            totalAmountPresent: {
                $cond: {
                    if: "$totalAmount",
                    then: 1,
                    else: 0
                }
            },
            cashbackAmountPresent: {
                $cond: {
                    if: "$cashbackAmount",
                    then: 1,
                    else: 0
                }
            },
            unitPricePresent: {
                $cond: {
                    if: "$unitPrice",
                    then: 1,
                    else: 0
                }
            }
        }
    },
    {
        $group: {   
            "_id": "$siteid",
            amountSum:   { "$sum": "$amount" },
            amountCount: { "$sum": "$amountPresent" },
            totalAmountSum:   { "$sum": "$totalAmount" },
            totalAmountCount: { "$sum": "$totalAmountPresent" },
            cashbackAmountSum:   { "$sum": "$cashbackAmount" },
            cashbackAmountCount: { "$sum": "$cashbackAmountPresent" },
            unitPriceSum:   { "$sum": "$unitPrice" },
            unitPriceCount: { "$sum": "$unitPricePresent" }
        }
    }
])