You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用MongoDB聚合实现按用户分组并展示各游戏得分列表?

问题

我有一个将游戏玩法数据存入MongoDB的API,该API接收gameId、userId和score参数,数据示例如下:

[
  {
    "gameId": "G1",
    "userId": "U22",
    "score": 420
  },
  {
    "gameId": "G2",
    "userId": "U22",
    "score": 10
  },
  {
    "gameId": "G1",
    "userId": "U22",
    "score": 80
  },
  {
    "gameId": "G1",
    "userId": "U25",
    "score": 400
  }
]

当游戏结束('Game Over')时会创建游戏得分文档,用户可在同一天内多次游玩。

目前我已通过以下聚合查询实现游戏排行榜:

db.plays.aggregate([
  {
    $group: {
      _id: '$userId',
      played: { $sum: 1 },
      score: { $sum: '$score' }
    }
  },
  { $limit: 100 },
  { $sort: { score: -1 } }
]);

查询输出如下:

[
  {
    "_id": "U22",
    "played": 3,
    "score": 510
  },
  {
    "_id": "U25",
    "played": 1,
    "score": 400
  }
]

现在我希望得到包含用户游玩游戏数组的结果,期望输出如下:

[
  {
    "_id": "U22",
    "played": [
      {
        "gameId": "G1",
        "score": 500
      },
      {
        "gameId": "G2",
        "score": 10
      }
    ],
    "score": 510
  },
  {
    "_id": "U25",
    "played": [
      {
        "gameId": "G1",
        "score": 400
      }
    ],
    "score": 400
  }
]

请问如何实现该需求?

解决方案

调整聚合管道,通过两层分组来实现需求,具体查询如下:

db.plays.aggregate([
  // 按用户+游戏分组,计算单游戏总得分
  {
    $group: {
      _id: {
        userId: "$userId",
        gameId: "$gameId"
      },
      gameScore: { $sum: "$score" }
    }
  },
  // 按用户分组,整理游戏列表并计算总得分
  {
    $group: {
      _id: "$_id.userId",
      played: {
        $push: {
          gameId: "$_id.gameId",
          score: "$gameScore"
        }
      },
      score: { $sum: "$gameScore" }
    }
  },
  // 按总得分降序排序
  { $sort: { score: -1 } },
  // 限制返回前100条结果
  { $limit: 100 }
]);

逻辑说明:

  1. 第一层$group:以userId和gameId的组合作为分组键,统计每个用户在单款游戏中的累计得分gameScore。
  2. 第二层$group:以userId为分组键,用$push将每个游戏的gameId和gameScore组装成对象存入played数组;同时用$sum累加所有游戏的得分,得到用户的总得分score。
  3. $sort:按用户总得分从高到低排序,符合排行榜的需求。
  4. $limit:限制返回前100条结果,与原查询逻辑保持一致。

内容的提问来源于stack exchange,提问作者Lahiru Supun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 09:31:04