Mongo 聚合嵌套数组,查找

Mongo Aggregate Nested Array, Lookup

我正在使用 MongoDB 和 Go 创建一个 Web 应用程序,其中包括基于角色的访问控制。我将有关此的信息存储在 2 个集合中,permissionsroles

这两个合集是这样的。 权限

{
    "operation": "create",
    "resource": "project"
}
{
    "operation": "read",
    "resource": "project"
}
{
    "operation": "update",
    "resource": "project"
}
{
    "operation": "delete",
    "resource": "project"
}
{
    "operation": "create",
    "resource": "user"
}

resource 是执行 operation 的东西。所以如果有一些操作不能在某些资源上执行,那么,我不需要存储它。例如,只能创建用户,因此只需要存储 create user。 目前在应用程序范围内只有 4 个操作(创建、读取、更新、删除),但可能会增加,例如 upload 可能会出现。

角色

{
    "role": "admin",
    "display_name": "Administrator",
    "permissions": [
      {
        "operation": "create",
        "resource": "project"
      },
      {
        "operation": "read",
        "resource": "project"
      },
      {
        "operation": "update",
        "resource": "project"
      },
      {
        "operation": "delete",
        "resource": "project"
      }
    ]
}

角色包含角色、要在UI上显示的角色名称以及该角色拥有的权限集。

我需要使用特定格式的 REST API 将此信息发送到 UI,这将描述特定角色是否可以使用 checked 标志以及使用标志 isEditable 对资源的特定操作是否可编辑。 例如,权限集合不包含对资源用户的删除操作,因此它不应是可编辑的,因此标志设置为 false。同样可以创建用户,因此设置为true。

 {
    display_name: "System Administrator",
    role: "admin",
    permissions: [
      {
        resource: "user",
        privilages: {
          create: { checked: false, isEditable: true },
          delete: { checked: false, isEditable: false },
          update: { checked: false, isEditable: false },
          read: { checked: false, isEditable: false }
        }
      },
      {
        resource: "project",
        privilages: {
          create: { checked: true, isEditable: true },
          delete: { checked: true, isEditable: true },
          update: { checked: true, isEditable: true },
          read: { checked: true, isEditable: true }
        }
      }
   ]
}

是否可以使用 mongo 聚合来执行此操作?或者我需要修改我的schema,如果是,那么我应该修改什么。

我能够通过 3 个步骤解决问题:

  1. 包括每个角色的所有权限并添加一个名为 checked 的标志。这增加了数据冗余,但这不是大问题。
  2. roles 集合中的 resource 字段上执行 group by
  3. 为每个 resource 填充缺失的 privileges,并在服务器端将 isEditable 设置为 false。

我不得不在服务器端遍历数据,但这是我能想到的最有效的方法。