2017-01-30 88 views
3

MongoDB 3.4集合将包含时间戳的传感器信息存储为ISODate字段。按日期分组MongoDB数据

传感器信息需要被不同地处理它们是否在天或夜晚,其中手段> = 20.00(下午8点)和< 08.00(上午08点)。我可以很容易地使用$hour来检查测量结果是否为晚上

根据要求,所有夜间测量属于晚上开始的日期,即21.00的测量日期适合,但需要从03.00的测量中减去一天。

我想要做的所有晚上措施的聚合,当晚的日期(一个$match步过滤掉了一整天的措施,这不是一个问题)和组。你有什么想法我可以做到这一点?我想过使用$project步骤并获取时间信息,但不知道如何生成可用于组操作的有效_id

回答

3

滤波部分可使用$addFields管道兼作以在$group_id键和随后$match管道中使用的字段来完成。这样的骨干是运营商,它将评估产生所需日期的要求中的条件。

$redact管道就足够了,但因为你还需要逻辑组过滤的文件,你还不如用$addFields管道创建具有这样的逻辑领域。

下面的例子说明这一概念:

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 } 
     } 
    } 
]) 

一个更详细的方法涉及使用在适当位置的$cond$switch情况下表达如下(感谢@Styvane):

db.sensors.aggregate([ 
    { 
     "$addFields": { 
      "yearMonthDay": { 
       "$switch": { 
        "branches": [ 
         { 
          "case": { "$lt": [ { "$hour": "$date" }, 8 ] }, 
          "then": { /* subtract one day from a measurement at < 08:00 */ 
           "$dateToString": { 
            "format": "%Y-%m-%d", 
            "date": { 
             "$subtract": [ 
              "$date", 
              1000 * 60 * 60 * 24 
             ] 
            } 
           } 
          } 
         }, 
         { 
          "case": { "$gte": [ { "$hour": "$date" }, 8 ] }, 
          "then": { /* 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 } 
     } 
    } 
]) 
+0

如何取代'$ cond'机智h'$ switch'? – styvane

+0

真的是一回事,取决于OP想要查询的详细程度,否则我相信性能方面不会有太大影响,如果我错了,请纠正我。 – chridam

+1

你是对的,我不想在这里迂腐,但它也使你的意图清楚,毕竟你在MongoDB 3.4中做这个:) – styvane