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

如何用纯MongoDB查询统计嵌套数组中玩家的游戏参与次数?

纯MongoDB查询:统计玩家参与游戏的总次数

需求说明

我需要基于以下房间文档结构,按user_name或user_id统计玩家在所有games数组中的总参与次数。例如玩家Andrew在第一个房间参与2场游戏,第二个房间参与1场,最终统计结果应为3。使用纯MongoDB聚合查询,不依赖Mongoose。

示例文档数据

[
  { // room data
    _id: '20ae0225-512a-405b-8b9f-d6ffdca6634c',
    games: [
      {
        _id: 'cb01da11-5809-43e6-b02e-e878b38f4e11',
        players: [
          { user_id: 'ef0d7656-38a1-4c82-982b-b4beb3941e07', user_name: 'Andrew' },
          { user_id: 'a13de96d-e137-41d8-bd5c-083d9dbc00d7', user_name: 'Jack' }
        ]
      },
      {
        _id: '9b03d0ef-178e-49d1-8b86-6b63c1957d6f',
        players: [
          { user_id: 'ef0d7656-38a1-4c82-982b-b4beb3941e07', user_name: 'Andrew' },
          { user_id: '67acb8b7-1670-4c07-979a-8a6e481bfd95', user_name: 'Thomas' }
        ]
      },
      {
        _id: '733a30d5-a6c1-4ce2-a33b-c8dbf61f2a2e',
        players: [
          { user_id: 'a13de96d-e137-41d8-bd5c-083d9dbc00d7', user_name: 'Jack' },
          { user_id: '67acb8b7-1670-4c07-979a-8a6e481bfd95', user_name: 'Thomas' }
        ]
      }
    ]
  },
  { // room data
    _id: '20ae0225-512a-405b-8b9f-d6ffdca6634c',
    games: [
      {
        _id: 'cb01da11-5809-43e6-b02e-e878b38f4e11',
        players: [
          { user_id: '67acb8b7-1670-4c07-979a-8a6e481bfd95', user_name: 'Thomas' },
          { user_id: 'a13de96d-e137-41d8-bd5c-083d9dbc00d7', user_name: 'Jack' }
        ]
      },
      {
        _id: '9b03d0ef-178e-49d1-8b86-6b63c1957d6f',
        players: [
          { user_id: 'ef0d7656-38a1-4c82-982b-b4beb3941e07', user_name: 'Andrew' },
          { user_id: '67acb8b7-1670-4c07-979a-8a6e481bfd95', user_name: 'Thomas' }
        ]
      },
      {
        _id: '733a30d5-a6c1-4ce2-a33b-c8dbf61f2a2e',
        players: [
          { user_id: 'a13de96d-e137-41d8-bd5c-083d9dbc00d7', user_name: 'Jack' },
          { user_id: '67acb8b7-1670-4c07-979a-8a6e481bfd95', user_name: 'Thomas' }
        ]
      }
    ]
  }
]

解决方案

1. 统计所有玩家的总参与次数

使用MongoDB聚合框架,通过多层拆分数组+分组统计实现:

db.your_collection_name.aggregate([
  // 拆分每个房间的games数组,每个game成为独立文档
  { $unwind: "$games" },
  // 拆分每个game的players数组,每个玩家成为独立文档(此时每条文档对应一次游戏参与记录)
  { $unwind: "$games.players" },
  // 按user_id和user_name分组,统计每个玩家的总参与次数
  {
    $group: {
      _id: {
        user_id: "$games.players.user_id",
        user_name: "$games.players.user_name"
      },
      total_games: { $sum: 1 }
    }
  },
  // 可选:重新整理输出字段,提升可读性
  {
    $project: {
      _id: 0,
      user_id: "$_id.user_id",
      user_name: "$_id.user_name",
      total_participated_games: "$total_games"
    }
  }
])

输出示例:

[
  { "user_id": "ef0d7656-38a1-4c82-982b-b4beb3941e07", "user_name": "Andrew", "total_participated_games": 3 },
  { "user_id": "a13de96d-e137-41d8-bd5c-083d9dbc00d7", "user_name": "Jack", "total_participated_games": 3 },
  { "user_id": "67acb8b7-1670-4c07-979a-8a6e481bfd95", "user_name": "Thomas", "total_participated_games": 4 }
]

2. 统计单个指定玩家的总参与次数

如果只需要统计某一个玩家的次数,可以在聚合流程中加入$match过滤条件:

按user_id查询

db.your_collection_name.aggregate([
  { $unwind: "$games" },
  { $unwind: "$games.players" },
  // 匹配目标玩家的user_id
  { $match: { "games.players.user_id": "ef0d7656-38a1-4c82-982b-b4beb3941e07" } },
  // 全局分组统计总次数
  {
    $group: {
      _id: null,
      total_games: { $sum: 1 }
    }
  },
  { $project: { _id: 0, total_participated_games: "$total_games" } }
])

按user_name查询

db.your_collection_name.aggregate([
  { $unwind: "$games" },
  { $unwind: "$games.players" },
  // 匹配目标玩家的user_name
  { $match: { "games.players.user_name": "Andrew" } },
  {
    $group: {
      _id: null,
      total_games: { $sum: 1 }
    }
  },
  { $project: { _id: 0, total_participated_games: "$total_games" } }
])

输出示例:

{ "total_participated_games": 3 }

内容的提问来源于stack exchange,提问作者Nguyen Kha Nam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 04:25:35