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

如何使用MongoDB Aggregate为每个文档添加总积分及百分比字段

问题描述

现有MongoDB文档如下:

{
"_id": "1",
"name": "KP",
"points": 20
},
{
"_id": "2",
"name": "Josh",
"points": 30
}, 
{
"_id": "3",
"name": "Angelo",
"points": 50
}

需要实现两个需求:

  • 计算所有文档points字段的总和(应为100),并将该总和作为total字段添加到每个文档中;
  • 基于总积分计算每个文档的points占比,生成percentage字段。

当前使用的聚合语句有误:

db.users.aggregate({$match:{}}, {$project: {_id: 1, name: 1, points: "$points"}}, {$group: {_id: "$name", total: {$sum: "$points"}}})
正确聚合方案

要实现需求,需先计算全局总积分,再将该值关联到每个文档,最后计算占比。以下提供两种适配不同MongoDB版本的方案:

方案1:使用$setWindowFields(MongoDB 5.0及以上版本推荐)

该方法无需额外分组和关联,直接通过窗口函数计算全局总和,写法更简洁高效:

db.users.aggregate([
  // 为每个文档添加全局points总和字段total
  {
    $setWindowFields: {
      partitionBy: null, // 全局范围计算,不做分区
      output: {
        total: { $sum: "$points" }
      }
    }
  },
  // 计算占比并保留两位小数(可根据需求调整精度)
  {
    $project: {
      _id: 1,
      name: 1,
      points: 1,
      total: 1,
      percentage: {
        $round: [ { $divide: [ "$points", "$total" ] }, 2 ]
      }
    }
  }
])

执行结果示例:

{ "_id": "1", "name": "KP", "points": 20, "total": 100, "percentage": 0.2 }
{ "_id": "2", "name": "Josh", "points": 30, "total": 100, "percentage": 0.3 }
{ "_id": "3", "name": "Angelo", "points": 50, "total": 100, "percentage": 0.5 }

方案2:兼容MongoDB 5.0以下版本

如果你的MongoDB版本低于5.0,可通过分组存总和、展开文档、计算占比的步骤实现:

db.users.aggregate([
  // 第一步:计算全局总积分,同时保留所有原始文档
  {
    $group: {
      _id: null,
      total: { $sum: "$points" },
      docs: { $push: "$$ROOT" }
    }
  },
  // 第二步:展开保存的文档数组
  { $unwind: "$docs" },
  // 第三步:整合字段并计算占比
  {
    $project: {
      _id: "$docs._id",
      name: "$docs.name",
      points: "$docs.points",
      total: 1,
      percentage: {
        $round: [ { $divide: [ "$docs.points", "$total" ] }, 2 ]
      }
    }
  }
])

原语句错误原因

原聚合语句存在三个核心问题:

  • $group按name分组,计算的是单个用户的积分总和,而非全局总积分;
  • 分组操作破坏了原始文档结构,无法将总积分关联回每个原始文档;
  • 缺少计算占比的关键步骤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 19:02:31