我的数据库中有以下结构的文档:
{
"reading_ts": ISODate(...),
"points": 2.3,
"user_id": 2
}
我每天每个user_id都会有更多这样的文件......数以百万计的...我想实现以下聚合:
- 获取一个月的数据
- 对每个user_id的数据进行分组
- 对每天的数据进行分组(因此我将拥有每天的数据,每个user_id(
- 获取每个用户每天的最大"积分">
- 计算有多少用户的最大点数低于值 10,有多少在 10 到 20 之间,有多少超过 20
我可以用$match执行第 1 步我可以使用这个来执行第 3 步:
{
"$group": {
"_id": {
"$subtract": [
"$reading_ts",
{
"$mod": [
{
"$toLong": "$reading_ts"
},
(1000 * 60 * 60 * 24)
]
}
]
}
}
}
问题是我现在不知道如何合并步骤 2 和 3。
您可以使用
$dayOfMonth
和$max
将步骤2,3和4组合在一个$group
阶段中,以获得每个用户每天的最大"积分"。
然后,您可以使用设置为 [0, 10, 20] 的 $bucket
运算符按存储桶计算用户数:
db.collection.aggregate([
{
"$match": {
"reading_ts": {
"$gte": ISODate("2019-01-01"),
"$lte": ISODate("2019-01-30")
}
}
},
{
"$group": {
"_id": {
"user": "$user_id",
"day": {
"$dayOfMonth": "$reading_ts"
}
},
"max": {
"$max": "$points"
}
}
},
{
"$bucket": {
"groupBy": "$max",
"boundaries": [
0,
10,
20
],
"default": 20,
"output": {
"users": {
"$sum": 1
},
}
}
}
])
在线试用: mongoplayground.net/p/jzZdz2V7R4-