【发布时间】:2015-12-22 23:29:16
【问题描述】:
以下是我的内容模型。
文档与定义有权访问文档的主体的用户和组 acl 相关联。 文档本身是一堆元数据和一个大型内容主体(从 pdfs/docs 等中提取)。
执行搜索的用户必须仅限于他/她有权访问的文档集(由文档上的 acl 定义)。由于用户 acls 或用户所属的组,他/她可以访问文档。 文档上的组成员身份和 acl 在本质上都是高度瞬态的,这意味着用户的组成员身份经常发生变化,文档本身的 ACL 也是如此。
方法 1 将文档上的 acl 及其元数据存储为非存储字段。将 ACL 中的组扩展到单个用户(因为 acl 可以是一个组)。 在查询时,将过滤器附加到用户查询,该过滤器将执行布尔过滤器以仅包含 acl 字段中具有用户 ID 的文档
"filter" : {
"query" : {
"term": {
"acls": "1234"
}
}
}
我看到这种方法的问题是,尽管文档元数据/内容没有改变,但文档需要重新索引。
每次用户的组成员更改时
每次文档上的 ACL 更改(文档的权限更改)
我假设这将导致大量的段创建和合并,尤其是因为文档正文(文档的字段之一)是一个相当大的文本部分。
方法 2: 这是对方法1的修改。当更新与acl严格相关时,这种方法试图限制文档上的更新。
而不是在元数据上定义 acl。这种方法需要创建多种类型
在文档索引中
Document (with metadata & text body) as a parent
id
text
userschild Document (parent id & user acls only). This document will exist for each parent
id
parentid
useracls
groupschild Document (parent id & group acls only). This document will exist for each parent with group acls
id
parentid
groupacls
在用户索引中 系统中每个用户的条目及其关联的组
User
id
groups
这里的想法是更新现在本地化到不同的 ElasticSearch 实体。 在用户 acl 更改的情况下,只会更新用户子文档(避免对父文档进行潜在的昂贵更新)。 如果组 acl 更改,则只会更新 groupschild 文档(再次避免对父文档进行潜在的昂贵更新)。 如果用户组成员再次更改,则只会更新二级索引(避免更新父文档)。
查询本身如下所示。
"filter" : {
"query" : {
"bool": {
"should": [
{
"has_child": {
"type": "userschild",
"query": {
"term": {
"users": "1234"
}
}
}
},{
"has_child": {
"type": "groupschild",
"query": {
"terms" : {
"groups" : {
"index" : "users",
"type" : "user",
"id" : "1234",
"path" : "groups"
}
}
}
}
}
]
}
}
}
由于所涉及的查询的性质,我对它的可扩展性存有疑问。它涉及两个术语查询,其中一个必须从单独的索引构建。我正在考虑使用启用了 docvalues 的字段来改进术语查找。
方法 2 会扩展吗?我担心的是 has_child 查询及其可扩展性。
有人可以澄清我在这方面的理解吗?
【问题讨论】:
-
如果您的客户端/应用程序知道 user_id,它是否也知道搜索者属于哪些组?给定搜索者的 user_id 和组,为什么不只过滤
matching group ACL或matching user ACL? -
原因是用户可能属于 1000 到 10000 个组,这会使组评估成为查询期间的瓶颈,并且一直是问题
-
确保您阅读了Practical Considerations for Parent-Child。涉及性能和内存考虑(因此水平可扩展性限制)。您是否必须在 Elastic 中管理您的 ACL?或者您可以在外部管理它们并直接引用文档上的主要群体(和个人用户)吗?
-
存储 acls 将允许在执行查询(而不是后过滤)的同时过滤文档并保持分面和页数不变。在我们的系统中,应用的 ACL 可以是用户/组或两者兼而有之。我已阅读父子文档。我们的用例表明,如果我们将 acl 拆分为 group-child 和 user-child,则父子比例将为 1 比 1,或者每个父节点可能有 2 个子节点。大量的 acl 更新是我们希望将 acl 更新分离到子文档并避免每次仅 acl 更改时都重新索引整个文档的原因
标签: elasticsearch acl