GroupBy 聚合,包括 mongo 中的缺失日期
Posted
技术标签:
【中文标题】GroupBy 聚合,包括 mongo 中的缺失日期【英文标题】:GroupBy Aggregation including missing dates in mongo 【发布时间】:2021-10-10 15:39:02 【问题描述】:我有一个聚合查询,当某个日期范围已过时,它会给我一个按日期分组的结果。示例聚合管道如下所示。
[
$match:
orderDate:
$gte: new Date('2021-08-01T00:00:00+05:30'),
$lte: new Date('2021-08-06T23:59:59+05:30'),
,
$group:
_id:
$dateToString:
format: '%Y-%m-%d',
date: '$orderDate',
]
这会获取类似于下面的结果
[
_id: '2021-08-01',
,
_id: '2021-08-02',
,
_id: '2021-08-04',
,
_id: '2021-08-05',
,
]
因此,请注意缺少第 03 天和第 6 天,因为它们不在集合中,但包含在聚合管道中传递的日期范围内。
有没有办法通过调整上述查询来直接查询和获取这些缺失的日期?这将导致正确的值
【问题讨论】:
【参考方案1】:也许下面的就是你想要的。
1)创建一个带有计数器的集合,例如这里 1-10 10 天
[
"date": 0
,
"date": 1
,
"date": 2
,
"date": 3
,
"date": 4
,
"date": 5
,
"date": 6
,
"date": 7
,
"date": 8
,
"date": 9
]
-
使用 $add 更新此集合并制作数据,10 个日期
在这里,我们从日期“2021-08-01T00:00:00+00:00”开始,我们将结束
在日期“2021-08-10T00:00:00+00:00”
这个更新会做(q=过滤器,u=更新,这里是它的管道更新)
"update": "dates",
"updates": [
"q": ,
"u": [
"$addFields":
"date":
"$add": [
"2021-08-01T00:00:00Z",
"$multiply": [
"$date",
24,
60,
60000
]
]
],
"multi": true
]
结果(10 个日期,1 天差)
"_id":
"$oid": "610c4bf99ccb15d9c9d67b55"
,
"date":
"$date": "2021-08-01T00:00:00Z"
,
"_id":
"$oid": "610c4bf99ccb15d9c9d67b56"
,
"date":
"$date": "2021-08-02T00:00:00Z"
,
"_id":
"$oid": "610c4bf99ccb15d9c9d67b57"
,
"date":
"$date": "2021-08-03T00:00:00Z"
...
3) 现在我们有 10 个日期的日期集合,所有日期相差 1 天 我们将使用订单集合进行 $lookup
订单收集
[
"_id": 1,
"date": "2021-08-01T00:00:00Z"
,
"_id": 2,
"date": "2021-08-01T00:00:00Z"
,
"_id": 3,
"date": "2021-08-05T00:00:00Z"
,
"_id": 4,
"date": "2021-08-03T00:00:00Z"
]
查询(取管道,先过滤想要的日期,只有当天下单才加入)
"aggregate": "dates",
"pipeline": [
"$match":
"$expr":
"$and": [
"$gte": [
"$date",
"$dateFromString":
"dateString": "2021-08-01T00:00:00"
]
,
"$lte": [
"$date",
"$dateFromString":
"dateString": "2021-08-05T00:00:00"
]
]
,
"$lookup":
"from": "orders",
"let":
"datesDate": "$date"
,
"pipeline": [
"$match":
"$expr":
"$eq": [
"$dateToString":
"format": "%Y-%m-%d",
"date": "$$datesDate"
,
"$dateToString":
"format": "%Y-%m-%d",
"date": "$date"
]
],
"as": "found-orders"
,
"$project":
"_id": 0
],
"cursor": ,
"maxTimeMS": 1200000
结果
[
"date": "2021-08-01T00:00:00Z",
"found-orders": [
"_id": 1,
"date": "2021-08-01T00:00:00Z"
,
"_id": 2,
"date": "2021-08-01T00:00:00Z"
]
,
"date": "2021-08-02T00:00:00Z",
"found-orders": []
,
"date": "2021-08-03T00:00:00Z",
"found-orders": [
"_id": 4,
"date": "2021-08-03T00:00:00Z"
]
,
"date": "2021-08-04T00:00:00Z",
"found-orders": []
,
"date": "2021-08-05T00:00:00Z",
"found-orders": [
"_id": 3,
"date": "2021-08-05T00:00:00Z"
]
]
这给出了每个日期(每天),当天的订单。 如果某一天没有下订单,则数组为空。 这里只有 10 天,您可以根据自己的需要进行 5 年的日期收集。
【讨论】:
以上是关于GroupBy 聚合,包括 mongo 中的缺失日期的主要内容,如果未能解决你的问题,请参考以下文章
数据分析—Pandas 中的分组聚合Groupby 高阶操作
Pandas groupby 和聚合输出应包括所有原始列(包括未聚合的列)