按日期分组MongoDB数据

时间:2017-01-30 07:18:43

标签: mongodb mongodb-query aggregation-framework

MongoDB 3.4集合将包含时间范围的传感器信息存储为ISODate字段。

传感器信息需要以不同方式处理,无论它们是还是,其中 night 表示> = 20.00(晚上8点) )和< 08.00(上午8点)。我可以轻松使用$hour来检查测量是 day 还是 night

根据要求,夜间的所有措施都属于夜间开始的日期,即21.00的测量日期适合,而需要从03.00的测量值中减去一天。

我想对所有 night 度量进行聚合($match步骤过滤掉所有日期度量,这不是问题)并按当晚的日期进行分组。你知道我怎么能这样做吗?我考虑使用$project步骤获取时间信息,但不确定如何生成可用于组操作的有效_id

1 个答案:

答案 0 :(得分:3)

过滤部分可以使用 $addFields 管道完成,该管道还用于创建要在 $group {{中使用的字段。 1}}密钥和后续的 $match 管道。其中的主干是 $cond 运算符,它将评估需求中的条件以生成所需的日期。

单个 $redact 管道就足够了,但由于您还需要使用逻辑对已过滤的文档进行分组,因此您也可以使用 $addFields 管道来创建具有这种逻辑的字段。

以下示例演示了这一概念:

_id

更详细的方法涉及使用 $switch 案例表达式代替 $cond ,如下所示(感谢@Styvane ):

db.sensors.aggregate([
    {
        "$addFields": {
            "yearMonthDay": {
                "$cond": [
                    { /* check if date hour is less than 8 */
                        "$lt": [
                            { "$hour": "$date" },
                            8
                        ]
                    },
                    { /* subtract one day from a measurement at < 08:00 */
                        "$dateToString": { 
                            "format": "%Y-%m-%d", 
                            "date": {
                                "$subtract": [
                                    "$date",
                                    1000 * 60 * 60 * 24
                                ]
                            }
                        } 
                    },
                    {  /* else return actual date */
                        "$dateToString": { 
                            "format": "%Y-%m-%d", 
                            "date": "$date" 
                        } 
                    }
                ]
            },
            "isNight": { 
                "$or": [
                    { "$gte": [ { "$hour": "$date" }, 21  ] },
                    { "$lt": [ { "$hour": "$date" }, 8  ] }
                ]
            }
        }
    },
    { "$match": { "isNight": true } },
    {
        "$group": {
            "_id": "$yearMonthDay",
            "count": { "$sum": 1 }
        }
    }
])