提取关于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 分钟时间段