MongoDB复杂聚合



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

{
    "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。

您可以使用

$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-

最新更新