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

MongoDB聚合查询:如何添加按动作分组统计的actions_total字段

MongoDB聚合查询:如何添加按动作分组统计的actions_total字段

你好呀!看了你现有的聚合管道和目标结果,其实只需要在现有步骤里加一个$addFields阶段,就能生成你需要的actions_total统计数组了,我来给你详细讲讲怎么改。

具体修改方案

在你当前计算total_score的$addFields阶段之后,新增一个$addFields阶段,用来对actions数组按动作分组统计数量和总分:

{
  $addFields: {
    "actions_total": {
      $map: {
        input: {
          $objectToArray: {
            $reduce: {
              input: "$actions",
              initialValue: {},
              in: {
                $mergeObjects: [
                  "$$value",
                  {
                    "$$this.action": {
                      count: { $add: [ { $ifNull: [ "$$value.$$this.action.count", 0 ] }, 1 ] },
                      total_score: { $add: [ { $ifNull: [ "$$value.$$this.action.total_score", 0 ] }, "$$this.score" ] }
                    }
                  }
                ]
              }
            }
          }
        },
        as: "stat",
        in: {
          action: "$$stat.k",
          count: "$$stat.v.count",
          total_score: "$$stat.v.total_score"
        }
      }
    }
  }
}

步骤拆解说明

  1. 用$reduce遍历统计:先遍历actions数组里的每一项,把相同动作的统计数据合并成一个键值对对象——键是动作名称,值是包含count(次数)和total_score(动作总分)的统计对象。
  2. 用$objectToArray转换结构:把上面得到的键值对对象转成数组,方便后续调整成你想要的格式。
  3. 用$map调整输出格式:把数组里的每一项映射成{action, count, total_score}的结构,和你目标里的格式完全匹配。

完整聚合管道

把这个新增阶段插入到你的现有管道中,最终完整的聚合管道如下:

[
  {
    $match: {
      timestamp: {
        $gte: ISODate('2022-11-17T00:00:00'),
        $lte: ISODate('2022-11-20T23:59:59')
      }
    }
  },
  {
    $lookup: {
      from: 'actions_score',
      localField: 'action',
      foreignField: 'action',
      as: 'score'
    }
  },
  {
    $unwind: { path: "$score" }
  },
  {
    $project: {
      'username': true,
      'action': true,
      'score': '$score.score',
      'timestamp': true,
      'role_id': true,
      '_id': false
    }
  },
  {
    $group: {
      _id: '$username',
      'username': { $first: '$username' },
      'role_id': { $first: '$role_id' },
      'actions': { $addToSet: '$$ROOT' }
    }
  },
  {
    $addFields: {
      'total_score': { "$sum": "$actions.score" }
    }
  },
  // 新增的统计阶段
  {
    $addFields: {
      "actions_total": {
        $map: {
          input: {
            $objectToArray: {
              $reduce: {
                input: "$actions",
                initialValue: {},
                in: {
                  $mergeObjects: [
                    "$$value",
                    {
                      "$$this.action": {
                        count: { $add: [ { $ifNull: [ "$$value.$$this.action.count", 0 ] }, 1 ] },
                        total_score: { $add: [ { $ifNull: [ "$$value.$$this.action.total_score", 0 ] }, "$$this.score" ] }
                      }
                    }
                  ]
                }
              }
            }
          },
          as: "stat",
          in: {
            action: "$$stat.k",
            count: "$$stat.v.count",
            total_score: "$$stat.v.total_score"
          }
        }
      }
    }
  },
  {
    $project: {
      _id: false,
      'actions.username': false,
      'actions.role_id': false
    }
  }
]

运行这个管道之后,就能得到包含actions_total字段的完整结果,完全符合你的预期需求~

备注:内容来源于stack exchange,提问作者MrOldSir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 14:28:01