MongoDB 3.4集合将包含时间范围的传感器信息存储为ISODate字段。
传感器信息需要以不同方式处理,无论它们是天还是晚,其中 night 表示> = 20.00(晚上8点) )和< 08.00(上午8点)。我可以轻松使用$hour
来检查测量是 day 还是 night 。
根据要求,夜间的所有措施都属于夜间开始的日期,即21.00的测量日期适合,而需要从03.00的测量值中减去一天。
我想对所有 night 度量进行聚合($match
步骤过滤掉所有日期度量,这不是问题)并按当晚的日期进行分组。你知道我怎么能这样做吗?我考虑使用$project
步骤获取时间信息,但不确定如何生成可用于组操作的有效_id
。
答案 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 }
}
}
])