正确的记录访问实现

pov*_*asp 8 lucene solr

我正在研究索引引擎,特别是Apache Lucene Solr.我们愿意将它用于我们的搜索,但我们的框架搜索解决的问题之一是行级访问.

Solr不提供开箱即用的记录访问:

<...> Solr不关心文档级别或通信级别的安全性.

在关于文档级安全性的部分中:http://wiki.apache.org/solr/SolrSecurity#Document_Level_Security

有一些建议 - 要么使用Manifold CF(高度无证,似乎处于非β前期阶段),要么编写自己的请求处理程序/搜索组件(该部分标记为存根) - 我想后者会有对性能的影响更大.

所以我假设在这个领域没有做太多.

在最近发布的4.0版Solr中,他们引入了两个索引实体.加入似乎是个好主意,因为我们的框架也会联系以了解该记录是否可供用户访问.这里的问题是,有时我们做一个内连接,有时和外连接(取决于乐观(允许禁止的一切)或悲观(一切都被禁止,只有明确允许的内容)范围内的安全设置).

为了更好地理解我们的结构:

文件

DocumentNr | Name
------------------
1          | Foo
2          | Bar
Run Code Online (Sandbox Code Playgroud)

DocumentRecordAccess

DocumentNr | UserNr | AllowRead | AllowUpdate | AllowDelete
------------------------------------------------------------
1          | 1      | 1         | 1           | 0
Run Code Online (Sandbox Code Playgroud)

因此,例如,在悲观安全设置中生成的文档查询将是:

SELECT * FROM Documents AS d 
INNER JOIN DocumentRecordAccess AS dra ON dra.DocumentNr=d.DocumentNr AND dra.AllowRead=1 AND dra.UserNr=1
Run Code Online (Sandbox Code Playgroud)

这只会返回foo,但不会返回bar.在乐观的环境中:

SELECT * FROM Documents AS d 
LEFT JOIN DocumentRecordAccess AS dra ON dra.DocumentNr=d.DocumentNr AND dra.AllowRead=1 AND dra.UserNr=1
Run Code Online (Sandbox Code Playgroud)

回归 - Foo和Bar.

回到我的问题 - 也许有人已经这样做了,可以分享他们的见解和经验吗?

min*_*das 7

恐怕这里没有简单的解决方案.您将不得不牺牲一些东西来使ACL与搜索一起工作.

  1. 如果您的语料库大小很小(我说最多10K文档),您可以创建一个禁用的(或允许的,任何更简洁的)文档的缓存位集并发送相关的过滤查询(+*:* -DocumentNr:1 ... -DocumentNr:X).不用说,这不会扩展.发送大型查询会使搜索速度变慢,但这是可管理的(当然是一个点).查询解析很便宜.

  2. 如果您可以以某种方式对这些文档进行分组并在文档组上应用ACL,这将允许缩短查询长度,并且上述方法将完全适合.这几乎就是我们正在使用的 - 我们的解决方案实现了分类,并通过fq查询完成了分类权限.

  3. 如果您不需要显示整体结果集计数,则可以运行查询并在客户端过滤结果集.再次,不完美.

  4. 您还可以对数据结构进行非规范化,并将两个表格平铺在单个文档中,如下所示:

    DocumentNr:1
    名称:Foo
    Allowed_users:u1,u2,u3(或Forbidden_​​users:...)

    其余的就像使用您的查询发送用户ID一样简单.

    如果ACL很少发生变化,并且您可以负担得起重建索引整个语料库,则上述情况才可行.

  5. 您可以编写一个自定义查询过滤器,该过滤器BitSet将从数据库中检索的用户(组?)缓存允许或禁止的文档.这不仅需要为Solr webapp提供数据库访问,还需要扩展/重新打包Solr附带的.war.虽然这相对容易,但更难的部分是缓存失效:当ACL数据发生变化时,主应用程序应以某种方式向Solr应用程序发出信号.

如果您可以将Solr和您的应用程序放在同一个JVM上并使用javabin驱动程序,则选项1和2可能更合理.

在不知道语料库/ ACL的细节的情况下,很难提供更多建议.

  • 我参与了上述建议(4)的实施,并且工作正常.我们使用了组和单个用户的组合,因此在组成员身份更改时并没有那么糟糕.我们还实现了一个可以获取权限的自定义请求处理程序,它确实略微影响了性能,但是值得. (2认同)