例如,我有文档A,B,C。用户1必须只能看到文档A,B。用户2必须只能看到文档C.是否可以在SOLR中进行,而无需按元数据过滤?如果我使用元数据过滤器,每次有访问权限更改时,我都必须重新编制索引。
[更新2/14/2012]不幸的是,在客户端的情况下,更改频繁。数据是保密的,通常仅由内部用户的所有者管理。然后,具体情况是他们需要能够将这些文档共享给某些外部用户并指定这些用户的访问级别。大多数情况下,这是一项临时任务,而且没有提前确定
答案 0 :(得分:9)
我建议将访问角色(是,它的复数)存储为文档元数据。这里,必需字段access_roles
是一个可分面的多值字符串字段。
Doc1: access_roles:[user_jane, manager_vienna] // Jane and the Vienna branch manager may see it
Doc2: access_roles:[user_john, manager_vienna, special_team] // Jane, the Vienna branch manager and a member of special team may see it
拥有该文档的用户是该文档的默认访问角色。
要更改文档的访问角色,请修改access_roles
。
当Jane搜索时,她所属的访问角色 将成为查询的一部分。 Solr将仅检索与用户访问角色匹配的文档。
当维也纳办事处(user_jane
)的经理Jane(manager_vienna
)搜索时,她的搜索结果如下:
q=mainquery
&fq=access_roles:user_jane
&fq=access_roles:manager_vienna
&facet=on
&facet.field=access_roles
获取user_jane
中包含manager_vienna
OR access_roles
的所有文档; Doc1
和Doc2
。
当Bob,(user_bob
),特殊团队成员(specia_team
)搜索时,
q=mainquery
&fq=access_roles:user_bob
&fq=access_roles:special_team
&facet=on
&facet.field=access_roles
为他取得Doc2
。
改编自http://wiki.apache.org/solr/SimpleFacetParameters#Multi-Select_Faceting_and_LocalParams
的查询答案 1 :(得分:6)
可能要查看文档级安全补丁。
https://issues.apache.org/jira/browse/SOLR-1872
https://issues.apache.org/jira/browse/SOLR-1834
答案 2 :(得分:3)
我认为我的方法与@ aitchnyu的回答类似。但是,我不会在元数据中使用单个用户。 如果您为每个文档创建组,那么您将不得不为安全原因重新编制索引。
对于给定的文档,您可能有access_roles:group_1,group_3
通过这种方式,group_1和group_3始终保留对文档的权限。但是,我可以改变每个用户所属的组,并相应地调整查询。
当生成查询时,它总是作为查询的一部分传递给用户的组。如果我属于group_1和group_2,我的查询将如下所示:
q=mainquery
&fq=access_roles:group_1
&fq=access_roles:group_2
由于组是在查询中动态生成的,因此我只是从组中删除用户,并且在发出新查询时,它们将不再在查询中包含已删除的组。因此,从group_1中删除用户将新建一个如下查询:
q=mainquery
&fq=access_roles:group_2
用户无法再访问所有需要第1组的文档。
这允许大多数更改实时完成,而不需要重新索引文档。出于安全原因,您必须重新索引的唯一原因是您决定某个特定组不再能够访问文档。
在许多现实场景中,这应该是相对不常见的事情。人力资源部门似乎总是可以获得人力资源部门,但是特定用户可能并不总是成为人力资源部门的一部分。
希望有所帮助。
答案 3 :(得分:3)
您可以使用Solr的PostFilter实现您的安全模型。有关详细信息,请参阅http://searchhub.org/2012/02/22/custom-security-filtering-in-solr/
注意:您应该缓存您的访问权限,否则性能会很糟糕。
答案 4 :(得分:2)
请记住,solr是基于纯文本的搜索引擎,索引系统,为了便于快速搜索,你不应该期望它的RDMS样式功能。 solr不为索引的文档提供安全性,如果需要,您必须编写这样的实现。在这种情况下,您有两个选择。 1)只需将文档索引到solr并将授权详细信息保存到RDBMS.Now查询solr中进行搜索并收集返回的结果。现在向DB发出另一个查询,查询solr返回的文档ID以查看用户是否可以访问它们或没有。过滤那些用户无法访问的文件。你完成了!但不是真的,你的问题只从这里开始。假设,如果solr返回的所有结果都被过滤掉了怎么办? (假设您一次不访问所有文档,意味着您只从solr结果集中检索前1000个结果,否则您无法快速搜索)您必须再次查询solr以获取下一组结果集并且必须迭代这些步骤直到您获得足够的结果才能显示。 2)第二种方法是将授权元数据与solr.Same中的文档一起索引,如aitchnyu所解释的那样。但是为了回答您对外部用户的文档共享的查询,以及用户组和角色细节,您可以索引这些外部用户的用户ID进入access_roles字段,或者你也可以在你的模式'access_user'中添加另一个字段。现在,您可以修改外部用户共享的搜索查询,以将access_user字段包含在筛选器查询中。 e.g
q=mainquery
&fq=access_roles:group_1
&fq=access_user:externaluserid
现在最重要的是,更新到索引文档。它的过程繁琐乏味的任务,但通过精心设计和异步处理以及solrs部分文档更新功能(solr 4.0 =>),您可以实现相当不错的TPS与solr。如果您使用solr< 4.0,您可以使用单独的系统进行搜索和更新,并且小心地充分利用负载均衡器和主从复制策略,您将面带微笑!
答案 5 :(得分:1)
我知道没有内置的Solr机制可以让您在不保留元数据权限的情况下控制对文档的访问。如果您保持真正的角色级别并且不为文档分配用户特定权限,那么aitchnyu概述的方法似乎是合理的。这样您就可以为用户分配角色,这将使他们能够查看索引中的文档。当然,您仍需要在角色更改时重新索引文档,但希望您可以在时间之前确定大部分所需的角色,并减少频繁重建索引的需要。