mongo组和有条件的计数

时间:2015-05-11 13:35:05

标签: mongodb mongodb-query aggregation-framework nosql

我试图对一组文档进行分组,并根据它们的值对它们进行计数。 例如

{ "_id" : 1, "item" : "abc1", "value" : "1" }
{ "_id" : 2, "item" : "abc1", "value" : "1" }
{ "_id" : 3, "item" : "abc1", "value" : "11" }
{ "_id" : 4, "item" : "abc1", "value" : "12" }
{ "_id" : 5, "item" : "xyz1", "value" : "2" }

在这里,我想分组" item"并获得一个计数"值"大于10且小了多少倍。所以:

{ "item": "abc1", "countSmaller": 2, "countBigger": 1}
{ "item": "xyz1", "countSmaller": 1, "countBigger": 0}

使用$ aggregate可以轻松实现普通计数,但我怎样才能达到上述结果?

2 个答案:

答案 0 :(得分:9)

您需要的是聚合框架的$cond运算符。获得你想要的东西的一种方法是:

db.foo.aggregate([
    {
        $project: {
            item: 1,
            lessThan10: {  // Set to 1 if value < 10
                $cond: [ { $lt: ["$value", 10 ] }, 1, 0]
            },
            moreThan10: {  // Set to 1 if value > 10
                $cond: [ { $gt: [ "$value", 10 ] }, 1, 0]
            }
        }
    },
    {
        $group: {
            _id: "$item",
            countSmaller: { $sum: "$lessThan10" },
            countBigger: { $sum: "$moreThan10" }
        }
    }
])

注意:我假设value为数字而不是字符串。

<强>输出:

{
        "result" : [
                {
                        "_id" : "xyz1",
                        "countSmaller" : 1,
                        "countBigger" : 0
                },
                {
                        "_id" : "abc1",
                        "countSmaller" : 2,
                        "countBigger" : 2
                }
        ],
        "ok" : 1
}  

答案 1 :(得分:0)

如果有人正在寻找这种情况的Java代码(根据我的需要更新了字段):

Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.project("environment").and("success").applyCondition(ConditionalOperators.when(Criteria.where("deploymentStatus").is("SUCCESS"))
                        .then(1)
                        .otherwise(0)).and("failed").applyCondition(ConditionalOperators.when(Criteria.where("deploymentStatus").is("FAILURE"))
                        .then(1)
                        .otherwise(0)),
                Aggregation.group("environment").sum("success").as("success").sum("failed").as("failed"));