8

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

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

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

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

很少有建议 - 要么使用 Manifold CF(它是高度无证的,而且似乎处于非常预测试阶段)或编写你自己的请求处理程序/搜索组件(该部分被标记为存根) - 我猜后者会有对性能的影响更大。

所以我认为在这个领域做的并不多。

在最近发布的 Solr 4.0 版本中,他们引入了连接两个索引实体。加入似乎是一个不错的主意,因为我们的框架也做了一个加入来了解用户是否可以访问记录。这里的问题是,有时我们会进行内部连接,有时会进行外部连接(取决于范围内的乐观(所有不被禁止的东西都是允许的)或悲观的(所有东西都是被禁止的,只有明确允许的)安全设置)。

为了更好地理解我们的结构是什么样的:

文件

DocumentNr | Name
------------------
1          | Foo
2          | Bar

文档记录访问

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。

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

4

2 回答 2

7

恐怕这里没有简单的解决方案。您必须牺牲一些东西才能让 ACL 与搜索一起工作。

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

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

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

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

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

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

    仅当 ACL 很少更改并且您可以在它们更改时重新索引整个语料库时,上述方法才可行。

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

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

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

于 2012-12-13T22:22:33.967 回答
3

我同意 mindas 的建议(sol-4),我以同样的方式实现了我的解决方案,但不同之处在于我几乎没有不同类型的 ACL。在用户组级别,用户级别甚至文档级别也是如此(私人访问)。

解决方案工作正常。但在我的案例中,主要担心的是 ACL 经常更改并且需要在索引中更新,这意味着搜索性能也不应该受到影响。

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

mindas,unicron,你能谈谈你的想法吗?

于 2012-12-20T13:08:08.800 回答