提取关于0值的时间,求一天中的多个工作时间,在MongoDB数组操作中

Posted

技术标签:

【中文标题】提取关于0值的时间,求一天中的多个工作时间,在MongoDB数组操作中【英文标题】:extract the time with respect to 0 value, find the multiple working hours in a day, in MongoDB array operations 【发布时间】:2021-11-06 16:48:25 【问题描述】:

说明: 我想从这个data 中提取time start end time。每当 0 到来时,这意味着它将是一个结束时间,如果下一个值大于 0,则它的新时间开始,我想在新时间开始时将文档拆分为多个文档,该值大于 0。

用例是:用户一天工作多次,而不是一整天(9:00 到 17:00)。例如,用户正在工作(9-10、11-12、15-16)。所以我们必须将文档拆分为 9-10、11-12、15-16。每当值为 0 时,则表示用户没有在工作,这将是时间结束。当值 > 0 时,表示用户重新开始工作。


    "data": ​
"2020-09-04T12:18:41Z": 0,
"2020-09-04T12:18:42Z": 1,
"2020-09-04T14:59:50Z": 1,
"2020-09-04T14:59:59Z": 0,
"2020-09-04T15:00:00Z": 0,
"2020-09-04T15:00:01Z": 1,
"2020-09-04T15:05:00Z": 1,
"2020-09-04T15:05:01Z": 0,
"2020-09-04T15:40:00Z": 0,
"2020-09-04T15:40:01Z": 1,
"2020-09-04T16:00:00Z": 1,
"2020-09-04T16:00:01Z": 0,
"2020-09-04T16:30:00Z": 0,
"2020-09-04T16:30:01Z": 1,
"2020-09-04T16:52:50Z": 1,
"2020-09-04T16:52:51Z": 0,
"2020-09-04T18:10:00Z": 0,
"2020-09-04T18:10:01Z": 1,
"2020-09-04T18:35:00Z": 1,
"2020-09-04T18:35:01Z": 0,
"2020-09-04T18:59:00Z": 0,
"2020-09-04T18:59:01Z": 1,
"2020-09-04T19:00:00Z": 1,
"2020-09-04T19:00:01Z": 0,
"2020-09-04T19:30:00Z": 0,
"2020-09-04T19:30:01Z": 1,
"2020-09-04T19:52:50Z": 1,
"2020-09-04T19:52:51Z": 0
​

【问题讨论】:

【参考方案1】:

当您使用实际值作为字段名称时,这是一个非常糟糕的设计。无论如何,您可以使用这样的聚合管道:

db.collection.aggregate([
   // Transform to array
    $set:  data:  $objectToArray: "$data"   ,
   // Sort the date values, bear in mind fields have an aribitary order, they are not sorted!
    $unwind: "$data" ,
    $sort:  "data.k": 1  ,
    $group:  _id: null, data:  $push:  k: "$data.k", v: "$data.v"    ,
   // do the actual logic
   
      $set: 
         data: 
            $reduce: 
               input: "$data",
               initialValue: [],
               in: 
                  $cond: 
                     if:  $eq: ["$$this.v", 0] ,
                     then: 
                        $concatArrays: [
                           "$$value",
                           [
                              k: "$$this.k",
                              v: "$$this.v",
                              group: 
                                 $cond: 
                                    if:  $ne: [ $last: "$$value.v" , 0] ,
                                    then:  $ifNull: [ $last: "$$value.group" , 0] ,
                                    else:  $add: [ $ifNull: [ $last: "$$value.group" , 0] , 1] 
                                 
                              

                           ]
                        ]
                     ,
                     else: 
                        $concatArrays: [
                           "$$value",
                           [
                              k: "$$this.k",
                              v: "$$this.v",
                              group:  $last: "$$value.group" 
                           ]
                        ]
                     
                  
               
            
         
      
   ,
   // Split into documents per group
    $unwind: "$data" ,
   
      $group: 
         _id: "$data.group",
         start_time:  $first: "$data.k" ,
         end_time:  $last: "$data.k" 
      
   
])

Mongo playground

【讨论】:

感谢您的回答:我同意您的观点,文档的设计非常糟糕。我尝试以不同的方式解决这个问题,你能检查一下吗?并且可以回答我如何从数组中获取元素,如果它后面只有 0。 if0isFollowedBy>=1 会或多或少相同。可以跳过前 4 个阶段。 但是如何检查情况?如果它后跟0或不在数组内?另外,从time_start中删除元素

以上是关于提取关于0值的时间,求一天中的多个工作时间,在MongoDB数组操作中的主要内容,如果未能解决你的问题,请参考以下文章

SQL 提取一天中所有未保留的 30 分钟或 60 分钟时间段

如何使用 Swift 获取一天中的时间?

颤动本地通知“一天中的小时,以 24 小时制 [0..23] 表示。”

怎样用sql查询一段时间内一天中的空闲时间和工作时间

SQL获取一天中的开始和结束时间

DateTimePicker - 如何将时间间隔设置为 20 分钟、一周中允许的特定日期和一天中的时间?