我的数据库中具有以下结构的文档:
{
"reading_ts": ISODate(...),
"points": 2.3,
"user_id": 2
}
每天每个user_id我都会有更多这样的文档...其中有数百万... 我想实现以下聚合:
我可以使用$ match进行第1步 我可以使用此步骤执行步骤3:
{
"$group": {
"_id": {
"$subtract": [
"$reading_ts",
{
"$mod": [
{
"$toLong": "$reading_ts"
},
(1000 * 60 * 60 * 24)
]
}
]
}
}
}
问题是我暂时不知道如何合并步骤2和3。
答案 0 :(得分:1)
您可以使用$dayOfMonth
和$max
在一个$bucket
阶段将步骤2、3和4合并在一起,以获取每个用户每天的最高“积分”。
然后,您可以使用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
},
}
}
}
])
运算符(存储区设置为[0、10、20])按存储分区对用户进行计数:
@Value("\${a}")
val a: Int = 0