Mongodb 聚合 - 今天按小时分组
Posted
技术标签:
【中文标题】Mongodb 聚合 - 今天按小时分组【英文标题】:Mongodb Aggregate - Grouping by hour for today 【发布时间】:2020-05-04 22:47:49 【问题描述】:我想知道是否有人可以帮助我正确设置聚合函数。我正在尝试计算我的健身访问量。我有访问表,其中保存了每次访问(从,到)日期。还保存了对某些服务的子访问。
[
"from": ISODate("2020-01-17T10:23:27.645Z"),
"to": ISODate("2020-01-17T12:23:28.760Z"),
"visits": [
"from": ISODate("2020-01-17T10:23:27.646Z"),
"to": ISODate("2020-01-17T10:30:28.760Z"),
"service": ObjectId("5e05f17d6b7f7920d4a62403")
,
"from": ISODate("2020-01-17T10:30:29.760Z"),
"to": ISODate("2020-01-17T12:23:28.760Z"),
"service": ObjectId("5d05f17dt57f7920d4a62404")
],
...
,
"from": ISODate("2020-01-17T10:40:00.000Z"),
"to": ISODate("2020-01-17T11:30:28.760Z"),
"visits": [
"from": ISODate("2020-01-17T10:40:00.000Z"),
"to": ISODate("2020-01-17T11:30:28.760Z"),
"service": ObjectId("h505f17s6b2f7920d4a6295y")
],
...
]
如果当前时间是 13:35,我想从 00:00 获得今天的结果,然后一直到 13:00,例如:
[
'date': '2020-01-18T00:00:0.000Z'
'visits': 0
,
'date': '2020-01-18T00:00:0.000Z'
'visits': 0
,
'date': '2020-01-18T00:00:0.000Z'
'visits': 0
,
'date': '2020-01-18T01:00:0.000Z'
'visits': 0
,
'date': '2020-01-18T02:00:0.000Z'
'visits': 0
,
'date': '2020-01-18T03:00:0.000Z'
'visits': 0
,
'date': '2020-01-18T04:00:0.000Z'
'visits': 0
,
'date': '2020-01-18T05:00:0.000Z'
'visits': 0
,
'date': '2020-01-18T06:00:0.000Z'
'visits': 0
,
'date': '2020-01-18T07:00:0.000Z'
'visits': 0
,
'date': '2020-01-18T08:00:0.000Z'
'visits': 0
,
'date': '2020-01-18T09:00:0.000Z'
'visits': 0
,
'date': '2020-01-18T010:00:0.000Z'
'visits': 2
,
'date': '2020-01-18T11:00:0.000Z'
'visits': 2
,
'date': '2020-01-18T12:00:0.000Z'
'visits': 1
,
'date': '2020-01-18T13:00:0.000Z'
'visits': 0
]
尝试了太多示例,但没有任何效果,请帮助!
【问题讨论】:
【参考方案1】:解释
如果我们使用$$NOW
,我们会得到当前日期。如果您手动设置currDate
、today
、nextDay
,MongoDB 聚合将限制所需的值。
现在,我们计算从today
(yyyy-MM-dd 00:00:00) - currDate
(yyyy-MM-dd 13:35:00) ~ 13 小时和$range
运算符创建数组
我们展平区间并应用过滤
你可以使用这样的查询:
db.collection.aggregate([
$addFields:
nextDay:
$add: [
$dateFromString:
dateString:
$substr: [
$toString: "$$NOW"
,
0,
10
]
,
format: "%Y-%m-%d"
,
$multiply: [
24,
60,
60,
1000
]
]
,
today:
$dateFromString:
dateString:
$substr: [
$toString: "$$NOW"
,
0,
10
]
,
format: "%Y-%m-%d"
,
currDate:
$dateFromString:
dateString:
$substr: [
$toString: "$$NOW"
,
0,
13
]
,
format: "%Y-%m-%dT%H",
timezone: "-01"
,
$addFields:
interval:
$range: [
0,
$add: [
$divide: [
$subtract: [
"$currDate",
"$today"
]
,
$multiply: [
60,
60,
1000
]
]
,
1
]
,
1
]
,
$unwind: "$interval"
,
$addFields:
date:
$add: [
"$today",
$multiply: [
"$interval",
60,
60,
1000
]
]
,
nextHour:
$add: [
"$today",
$multiply: [
$add: [
"$interval",
1
]
,
60,
60,
1000
]
]
,
$project:
_id: 0,
date: 1,
today: 1,
nextDay: 1,
visits:
$reduce:
input: "$visits",
initialValue: 0,
in:
$add: [
"$$value",
$cond: [
$or: [
$and: [
$gte: [
"$$this.from",
"$date"
]
,
$lte: [
"$$this.from",
"$nextHour"
]
]
,
$and: [
$lte: [
"$date",
"$$this.to"
]
,
$gte: [
"$date",
"$$this.from"
]
]
]
,
1,
0
]
]
,
$match:
$expr:
$and: [
$gte: [
"$date",
"$today"
]
,
$lte: [
"$date",
"$nextDay"
]
,
]
,
$group:
_id: "$date",
visits:
$sum: "$visits"
,
$sort:
_id: 1
])
MongoPlayground
JS设置,点击here
如果你想要更优雅的方式,你可以尝试this 解决方案
【讨论】:
我们可以使用 javascript 变量中的 startDate 和 endDate 吗? 当然。设置currDate
、nextDay
和 today
值
看看https://mongoplayground.net/p/tYDbBghxn16
确保您复制粘贴了我的代码的最新版本
好的,谢谢你帮助我。现在我有最后一个问题,它正在承受我的健身负担。就像我的访问时间是从 10:00 到 12:30,我需要显示在 10:00 访问 1 次,在 11:00 访问 1 次,并且在 12:00 还访问 1 次。我怎样才能达到这个逻辑?以上是关于Mongodb 聚合 - 今天按小时分组的主要内容,如果未能解决你的问题,请参考以下文章