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

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"] }
            }
          }
        ]
      }
    }
  }
])

代码说明

  1. $match:精准过滤出resource1的记录,减少后续处理的数据量。
  2. $lookup:通过resource-policies.permissions中的角色项匹配role-permissions.name,获取对应角色的权限集合。
  3. $project:
    • 用$filter提取原权限中的直接权限(非角色项)。
    • 用$reduce+$concatArrays将所有角色的权限数组展开并合并为扁平数组。
    • 最后用$concatArrays合并直接权限与角色权限,得到完整权限列表。

可选:权限去重

如果存在重复权限,可在最后添加以下阶段实现去重:

{
  $addFields: {
    permissions: { $setUnion: ["$permissions"] }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 23:06:10