以下是我的内容模型。
文档与用户和组ACL相关联,这些用户和组ACL定义了有权访问文档的主体。
该文档本身是一堆元数据和一个庞大的内容主体(从pdfs / docs等中提取)。
执行搜索的用户必须仅限于他/她有权使用的文档集(由文档上的ACL定义)。由于用户acls或由于用户所属的组,他/她可以访问文档。
文档中的组成员身份和ACL本质上都是高度 transient 的,这意味着用户的组成员身份会经常更改,文档本身上的ACL也经常更改。
方法1
将acl和它的元数据一起存储在文档中,作为未存储的字段。将ACL中的组扩展到单个用户(因为acl可以是一个组)。
在查询时,将过滤器附加到用户查询,该查询将进行 bool(boolean) 过滤,以仅在acl字段中包含具有用户ID的文档
"filter" : {
"query" : {
"term": {
"acls": "1234"
}
}
}
我看到的这种方法的问题是,尽管文档元数据/内容未更改,但文档仍需要重新编制索引。
每次用户的组成员身份更改
每次文档上的ACL更改(文档的权限更改)
我假设这将导致大量的段创建和合并,尤其是因为文档主体(文档的字段之一)是一个很大的文本部分。
方法二:
这是对方法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更改,则只会更新userschild文档(避免对父文档进行可能昂贵的更新)。
在更改组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"
}
}
}
}
}
]
}
}
}
由于要涉及的查询的性质,我对其可扩展性有疑问。它涉及两个术语查询,其中之一必须从单独的索引中构建。我正在考虑使用启用了docvalue的字段来改善术语查找。
方法2会扩展吗?我关心的是有关has_child查询及其可伸缩性的问题。
有人可以澄清我在这方面的理解吗?
最佳答案
我认为这可能是因为在查询之前扩展组而变得过于复杂。如何在文档索引中保留原样的组标识符呢?
通常,我用两个索引来表示(没有父子关系,或者根本没有任何嵌套关系)。
用户索引
(样本文档)
{
"user_id": 12345,
"user_name": "Swami PR"
"user_group_ids": [900, 901, 902]
}
文档索引
(样本文档)
{
"doc_id": 98765,
"doc_name": "Lunch Order for Tuesday - Top Secret and Confidential",
"doc_acl_read_users": [12345, 12346, 12347],
"doc_acl_write_users": [12345],
"doc_acl_read_groups": [435, 620],
"doc_acl_write_groups": []
}
该用户索引可以很容易地存在于数据库中...您的应用程序在查询文档时只需要可用的“Swami”的
user_id
和group_ids
。然后,当您将
[Top Secret]
文档查询为Swami PR
时(要读取),请确保添加:"should": [
{
"term": {
"doc_acl_read_users": 12345
}
},
{
"terms": {
"doc_acl_read_groups": [900, 901, 902]
}
},
"minimum_should_match": 1
]
我可以看到两种主要的更新类型:
带边盒
关于elasticsearch - ElasticSearch内容ACL过滤性能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34426183/