【问题标题】:Multiple timerange group in days of data数据天数中的多个时间范围组
【发布时间】:2018-12-31 16:48:14
【问题描述】:

我试图在 24 小时内获取三个不同时间范围的第一个和最后一个文档,然后按天分组。

一天的时间范围

第 1 天

T1 : 06:00 - 17:00 - 获取第一个和最后一个文档

T2 : 17:00 - 22:00 - 获取第一个和最后一个文档

T3 : 22:00 - 06:00 - 获取第一个和最后一个文档

第 2 天.. 以此类推

示例文档

{ 
"_id" : ObjectId("5ba6bc27260d0909e43b0874"), 
"_DeviceName" : "Ground Floor", 
"PointType" : "Building", 
"_DeviceID" : ObjectId("5b9ae3a76080700be0f173d6"), 
"_TariffID" : ObjectId("5a8893216b41bd32c0797f91"), 
"_Timestamp" : ISODate("2018-09-22T22:03:18.552+0000"), 
"_ModbusID" : 1, 
"_LocationID" : ObjectId("5b9ae0eb6080700be0f173bf"),
"Registers" : {
    "quadrant4reactiveenergyL3" : 781.0, 
    "quadrant4reactiveenergyL2" : 74.0, 
    "quadrant4reactiveenergyL1" : 144.0, 
    "quadrant1reactiveenergyL3" : 52.0, 
    "quadrant1reactiveenergyL2" : 706.0, 
    "quadrant1reactiveenergyL1" : 185.0, 
    "totalharmonicdistorsionVL3" : 3.3000000000000003, 
    "totalharmonicdistorsionVL2" : 3.5, 
    "totalharmonicdistorsionVL1" : 3.6, 
    "consumedactiveenergyL3" : 9144.0, 
    "consumedactiveenergyL2" : 21774.0, 
    "consumedactiveenergyL1" : 18509.0, 
    "totalconsumedactiveenergy" : 49445.0, 
}}

我尝试做的是以下内容; 按时间分组,但无法获取每个条件的第一个和最后一个元素。

"$project": {
            "yearMonthDayUTC": {
                "$dateToString": {
                    "format": "%Y-%m-%d",
                    "date": "$_Timestamp"
                }
            },
            "timewithOffset": {
                "$dateToString": {
                    "format": "%H:%M:%S",
                    "date": "$_Timestamp"
                }
            },
            "Registers.totalconsumedactiveenergy": 1.0,
            "_DeviceID": 1.0
        }
"$group": {
            "_id": {
                "Date": "$yearMonthDayUTC",
                "Device": "$_DeviceID"
            },
            "T1": {
                "$sum": {
                    "$cond": [
                        {
                            "$and": [
                                {
                                    "$gte": [
                                        "$timewithOffset",
                                        "06:00:00"
                                    ]
                                },
                                {
                                    "$lte": [
                                        "$timewithOffset",
                                        "17:00:00"
                                    ]
                                }
                            ]
                        },
                        1.0,
                        0.0
                    ]
                }
            },
            "T2": {
                "$sum": {
                    "$cond": [
                        {
                            "$and": [
                                {
                                    "$gte": [
                                        "$timewithOffset",
                                        "17:00:00"
                                    ]
                                },
                                {
                                    "$lte": [
                                        "$timewithOffset",
                                        "22:00:00"
                                    ]
                                }
                            ]
                        },
                        1.0,
                        0.0
                    ]
                }
            },
            "firstactive": {
                "$first": "$$ROOT.Registers.totalconsumedactiveenergy"
            },
            "lastactive": {
                "$last": "$$ROOT.Registers.totalconsumedactiveenergy"
            }
        }
    }, 

我期待看到这样的东西

第 1 天:2018 年 12 月 12 日

T1 - 第一个文档,最后一个文档

T2 - 第一个文档,最后一个文档

T3 - 第一个文档,最后一个文档

第 2 天:2018 年 12 月 13 日

T1 - 第一个文档,最后一个文档

T2 - 第一个文档,最后一个文档

T3 - 第一个文档,最后一个文档

...

【问题讨论】:

  • 您可以发布示例文件吗?
  • 更新了我的问题
  • 发布的文档没有 yearMonthDayUTC 和 timewithOffset 字段
  • 好在查询代码中添加项目阶段

标签: c# mongodb mongodb-query


【解决方案1】:

请尝试以下聚合管道,如果您想要完整的$first$last 文档,您需要使用$$ROOT

db.t18.aggregate([
    {$group: {_id : {
        date : {$dateToString: {format : "%Y-%m-%d", date : "$_Timestamp"}}, 
        T : {$switch : 
            {branches: [
                {case: {$and: [{$gte : [{$hour : "$_Timestamp"}, 6]},{$lt : [{$hour : "$_Timestamp"}, 17]}]}, then : "T1"},
                {case: {$and: [{$gte : [{$hour : "$_Timestamp"}, 17]},{$lt : [{$hour : "$_Timestamp"}, 22]}]}, then : "T2"}
            ],
            default : "T3"
        }}},
        firstactive : {$first : "$Registers.totalconsumedactiveenergy"},
        lastactive : {$last : "$Registers.totalconsumedactiveenergy"}
    }},
    {$group: {_id : {date : "$_id.date"}, data : {$push : {"k" : "$_id.T", "v" : ["$firstactive","$lastactive"]}}}},
    {$project: {_id : 0, date : "$_id.date", "data" : {$arrayToObject : "$data"}}}
]).pretty()

【讨论】:

  • 谢谢你,真的。我想有一件事使聚合感到困惑,因为文档具有具有相似仪表数据的不同设备,这些设备也需要按“_DeviceID”分组,因此每个设备都有自己的日期和时间范围。那也可以添加吗? "_id" : { "date" : "2018-12-31", "T" : "T1" }, "firstactive" : 499796233.0, "lastactive" : 22693981.0 这就是我得到的,你可以看到 lastactive 低于firstactive,那是因为可能是从其他设备的数据中读取的
  • 您可以在$group _id 字段中添加_DeviceID,也可以在$sort 前添加_Timestamp
猜你喜欢
  • 2012-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-29
  • 1970-01-01
  • 1970-01-01
  • 2012-08-05
  • 1970-01-01
相关资源
最近更新 更多