MongoDB中的条件分组

时间:2014-06-11 01:50:53

标签: mongodb mongodb-query aggregation-framework

我在MongoDB中有一系列文档(检查事件),如下所示:

{
    "_id" : ObjectId("5397a78ab87523acb46f56"),
    "inspector_id" : ObjectId("5397997a02b8751dc5a5e8b1"),
    "status" : 'defect',
    "utc_timestamp" : ISODate("2014-06-11T00:49:14.109Z")
}

{
    "_id" : ObjectId("5397a78ab87523acb46f57"),
    "inspector_id" : ObjectId("5397997a02b8751dc5a5e8b2"),
    "status" : 'ok',
    "utc_timestamp" : ISODate("2014-06-11T00:49:14.109Z")
}

我需要得到一个如下所示的结果集:

[
  {
    "date" : "2014-06-11",
    "defect_rate" : '.92' 
  },  
  {
    "date" : "2014-06-11",
    "defect_rate" : '.84' 
  }, 
]

换句话说,我需要每天获得平均缺陷率。这可能吗?

2 个答案:

答案 0 :(得分:16)

聚合框架就是您想要的:

db.collection.aggregate([
    { "$group": {
        "_id": {
            "year": { "$year": "$utc_timestamp" },
            "month": { "$month": "$utc_timestamp" },
            "day": { "$dayOfMonth": "$utc_timestamp" },
        },
        "defects": {
            "$sum": { "$cond": [
                { "$eq": [ "$status", "defect" ] },
                1,
                0
            ]}
        },
        "totalCount": { "$sum": 1 }
    }},
    { "$project": {
        "defect_rate": {
            "$cond": [
                { "$eq": [ "$defects", 0 ] },
                0,
                { "$divide": [ "$defects", "$totalCount" ] }
            ]
        }
    }}
])

首先,您使用date aggregation operators在当天进行分组,并在指定日期获取项目的totalCount。这里使用$cond运算符确定“状态”是否实际上是缺陷,结果是条件$sum,其中只计算“缺陷”值。

每天对这些内容进行分组后,您只需$divide结果,再使用$cond进行检查,以确保不会将其除以零。

答案 1 :(得分:1)

这是解决更新问题的最佳方法吗?

$group : {
                _id        : '$symbol',
                amount     : {
                    $sum : '$amount'
                },
                value      : {
                    $sum : '$value'
                },
                occurences : {
                    $sum : 1
                },
                in         : {
                    $sum : {
                        $cond : [
                            {
                                $eq : [
                                    '$direction',
                                    'IN'
                                ]
                            },
                            1,
                            0
                        ]
                    }
                },
                out        : {
                    $sum : {
                        $cond : [
                            {
                                $eq : [
                                    '$direction',
                                    'OUT'
                                ]
                            },
                            1,
                            0
                        ]
                    }
                }
            }