正确的记录访问实现

时间:2012-12-13 18:26:08

标签: solr lucene

我正在研究索引引擎,特别是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

DocumentRecordAccess

DocumentNr | UserNr | AllowRead | AllowUpdate | AllowDelete
------------------------------------------------------------
1          | 1      | 1         | 1           | 0

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

SELECT * FROM Documents AS d 
INNER JOIN DocumentRecordAccess AS dra ON dra.DocumentNr=d.DocumentNr AND dra.AllowRead=1 AND dra.UserNr=1

这只会返回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

返回两者 - Foo和Bar。

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

2 个答案:

答案 0 :(得分:7)

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

  1. 如果你的语料库大小很小(我说最多10K文档),你可以创建一个禁止(或允许,不管那么详细)文档的缓存位集并发送相关的过滤查询{{1} }。不用说,这不会扩展。发送大型查询会使搜索速度变慢,但这是可管理的(当然是一个点)。查询解析is cheap

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

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

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

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

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

    如果ACL很少改变,那么只有当他们能够重新索引整个语料库时,才能生效。

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

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

    如果不了解语料库/ ACL的具体细节,很难提出更多建议。

答案 1 :(得分:3)

我同意mindas,他建议的内容(sol-4),我已经以同样的方式实现了我的解决方案,但区别在于我有几种不同类型的ACL。在用户组级别,用户级别甚至文档级别(私人访问)。

解决方案工作正常。但在我的情况下,主要关注的是ACL经常更改并且需要在索引中更新,这意味着搜索性能也不会受到影响。

我正在尝试通过负载平衡和向集群添加更多节点来管理它。

mindas,unicron你可以把你的想法放在这个吗?