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: [ {}, {}, {}, {} ] } ]
解决方案
你的代码存在两处问题:
- 聚合管道的每个阶段必须是数组中的独立对象,你把两个
$group阶段放在同一个对象里,属于语法错误。 - 第二个
$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
相关产品推荐
相关产品推荐

