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

MongoDB聚合管道:如何按字段分组并收集另一字段值?

MongoDB聚合管道分组权限数据问题

集合数据

我的permission集合中有如下文档:

[
  {
    _id: new ObjectId("62f695063cf6055e6a50fd6d"),
    permissionGroupName: 'User Management',
    permissionName: 'Create User',
    __v: 0
  },
  {
    _id: new ObjectId("62f695063cf6055e6a50fd6f"),
    permissionGroupName: 'User Management',
    permissionName: 'Edit User',
    __v: 0
  },
  {
    _id: new ObjectId("62f695063cf6055e6a50fd71"),
    permissionGroupName: 'User Management',
    permissionName: 'Delete User',
    __v: 0
  },
  {
    _id: new ObjectId("62f695073cf6055e6a50fd73"),
    permissionGroupName: 'User Management',
    permissionName: 'Approve User',
    __v: 0
  },
  {
    _id: new ObjectId("62f8a73c79a839650a183182"),
    permissionGroupName: 'Country Management',
    permissionName: 'Approve Country',
    __v: 0
  },
  {
    _id: new ObjectId("62f8ad3c79a839650a113184"),
    permissionGroupName: 'Country Management',
    permissionName: 'Delete Country',
    __v: 0
  },
]

期望输出

我希望通过MongoDB聚合管道按permissionGroupName字段分组,将对应的permissionName值收集到permissions数组中,期望输出如下:

[
  {
    permissionGroupName: "User Management",
    permissions: ["Create User", "Edit User", "Delete User", "Approve User"],
  },
  {
    permissionGroupName: "Country Management",
    permissions: ["Approve Country", "Delete Country"],
  },
];

尝试的代码及错误输出

我尝试了以下代码:

[
      {
        $group: {
          _id: {
            permissionGroupName: "$permissionGroupName",
            permissionName: "$permissionName",
          },
        },
        $group: {
          _id: "$permissionGroupName",
          permissions: {
            $push: {
              permission: "$_id.permissonName",
            },
          },
        },
      },
    ]

但得到了无效输出:

[
  { _id: 'Country Management', permissions: [ {} ] },
  { _id: 'User Management', permissions: [ {}, {}, {}, {} ] }
]

解决方案

你的代码存在两处问题:

  1. 聚合管道的每个阶段必须是数组中的独立对象,你把两个$group阶段放在同一个对象里,属于语法错误。
  2. 第二个$group阶段存在字段拼写错误:permissonName应为permissionName;且不需要嵌套对象,直接推送字段值即可。

正确的聚合管道如下:

[
  {
    $group: {
      _id: "$permissionGroupName",
      permissions: { $push: "$permissionName" }
    }
  },
  {
    $project: {
      _id: 0,
      permissionGroupName: "$_id",
      permissions: 1
    }
  }
]

步骤说明:

  • 第一个$group阶段:按permissionGroupName分组,将同组的permissionName收集到permissions数组中,此时分组的_id就是权限组名称。
  • 第二个$project阶段:重新构造输出文档,移除_id字段,将原_id的值映射为permissionGroupName字段,保留permissions数组,最终输出符合预期格式的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 12:15:42