MongoDB复杂聚合

时间:2019-06-21 10:23:16

标签: mongodb aggregate

我的数据库中具有以下结构的文档:

{
    "reading_ts": ISODate(...),
    "points": 2.3,
    "user_id": 2
}

每天每个user_id我都会有更多这样的文档...其中有数百万... 我想实现以下聚合:

  1. 获取一个月的数据
  2. 将每个user_id的数据分组
  3. 将每天的数据分组(因此我将获得每个user_id的每天的数据)
  4. 获取每天每位用户的最高“积分”
  5. 计算有多少用户的最大积分值低于10,有多少在10到20之间以及有多少在20以上

我可以使用$ match进行第1步 我可以使用此步骤执行步骤3:

{
    "$group": {
        "_id": {
            "$subtract": [
                "$reading_ts",
                {
                    "$mod": [
                        {
                            "$toLong": "$reading_ts"
                        },
                        (1000 * 60 * 60 * 24)
                    ]
                }
            ]
        }
    }
}

问题是我暂时不知道如何合并步骤2和3。

1 个答案:

答案 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

在线试用:mongoplayground.net/p/jzZdz2V7R4-