MongoDB聚合:合并集合与$lookup结果中的权限数组
MongoDB聚合:合并资源权限与角色权限
我有resource-policies和role-permissions两个集合,需要获取resource1的所有权限,包括匹配的role-permissions记录中的权限。
集合结构
resource-policies集合
{ "resource": "resource1", "permissions": [ "permission:read", "role:admin" ] }
role-permissions集合
{ "name": "role:admin", "permissions": ["permission:write", "permission:delete"] }
期望结果
[ { "resource": "resource1", "permissions": [ "permission:read", "permission:write", "permission:delete" ] } ]
原代码问题分析
- $lookup关联字段错误:原代码将
foreignField设为permissions,但role-permissions中用来匹配角色的字段是name,导致无法正确关联到对应的角色权限记录。 - 权限合并逻辑错误:
$map无法直接展开角色对应的权限数组并合并到总权限中,且$rolePermissions是数组类型,直接比较$$this和$rolePermissions.name永远不成立,最终无法替换角色项为对应权限。
正确聚合代码
resourcePoliciesCollection.aggregate([ // 匹配目标资源记录 { $match: { resource: "resource1" } }, // 关联角色权限集合,通过角色名匹配 { $lookup: { from: "role-permissions", localField: "permissions", foreignField: "name", as: "rolePermissions" } }, // 合并直接权限与角色权限 { $project: { _id: 0, resource: 1, permissions: { $concatArrays: [ // 筛选出原权限中的直接权限(排除以role:开头的项) { $filter: { input: "$permissions", cond: { $not: { $regexMatch: { input: "$$this", regex: "^role:" } } } } }, // 展开并合并所有角色对应的权限数组 { $reduce: { input: "$rolePermissions.permissions", initialValue: [], in: { $concatArrays: ["$$value", "$$this"] } } } ] } } } ])
代码说明
- $match:精准过滤出
resource1的记录,减少后续处理的数据量。 - $lookup:通过
resource-policies.permissions中的角色项匹配role-permissions.name,获取对应角色的权限集合。 - $project:
- 用
$filter提取原权限中的直接权限(非角色项)。 - 用
$reduce+$concatArrays将所有角色的权限数组展开并合并为扁平数组。 - 最后用
$concatArrays合并直接权限与角色权限,得到完整权限列表。
- 用
可选:权限去重
如果存在重复权限,可在最后添加以下阶段实现去重:
{ $addFields: { permissions: { $setUnion: ["$permissions"] } } }
内容的提问来源于stack exchange,提问作者bflemi3
相关产品推荐
相关产品推荐

