Sphinx搜索引擎使用访问权限表

时间:2012-03-19 18:20:20

标签: database sphinx

我想在搜索sphinx索引时检查正在寻找某些文档的用户的读取权限。

例如,我有一个doc_id,doc_title和doc_is_global的文档表。另一方面,我有一个accessprivileges表,其结构如下:

user_id,user_group_id,doc_id,doc_category_id

用户可以分组为“user_group”,标识符为user_group_id,文档等效为document_categories。

访问表可能如下所示:

  

user_id,user_group_id,doc_id,doc_category_id

     

1,NULL,1,NULL

     

NULL,12,NULL,32

     

1,NULL,NULL,31

     

NULL,10,1,NULL

用户应该只找到is_global标志设置为1的文档,或者他可以通过user_id或者他是其成员的group_id进行访问。

在普通的MySQL中,我得到了一些JOIN的正确结果,如:

    SELECT * from documents d
    LEFT JOIN document_category dc ON dc.doc_id = d.doc_id
    LEFT JOIN access a ON a.user_id = {$user} and a.doc_id = d.doc_id
    LEFT JOIN access a ON a.category_id = dc.category_id and dc.group_id IN ({$groups})
    [...]

在Sphinx中,我知道,我可以将多个属性放到索引文档中,但这不是我想要的。在我富有成效的环境中,我还要检查哪个用户已经提供了读访问权限,并且只有他能够这样做,用户才能成为读取权限。 使用sphinx制作具有多个属性的情况,它返回类似于:

access_user_id =(1,4,6,2)visited_by_user =(1,5,3)

所以没有可能检查谁给谁谁读取权限。接下来的问题是Sphinx只支持max。每个索引4gb属性。

我需要一些提示来构建索引来过滤掉用户不允许看到的结果(可能有多个索引?)

1 个答案:

答案 0 :(得分:2)

您可以使用

对其进行索引
sql_query = 
  SELECT d.doc_id, ...
    GROUP_CONCAT(a.user_id) AS access_user_id,
    GROUP_CONCAT(a.user_group_id) AS access_user_group_id
  FROM documents d
    LEFT JOIN document_category dc ON (dc.doc_id = d.doc_id)
    LEFT JOIN access a ON (a.doc_id = d.doc_id OR a.doc_category_id = dc.category_id)
  GROUP BY doc_id

然后可以过滤

$cl->setSelect("*, IF(IN({$user},access_user_id),1,0)+IF(IN({$group},access_user_group_id),1,0) AS myint");
$cl->setFilter('myint',array(1,2));
  

接下来的问题是Sphinx只支持max。每个索引4gb属性。

Sphinx每个索引仅支持4gb 字符串属性。你确定MVA属性有这样的限制吗?

在任何情况下,如果属性太多 - 限制是每个索引。因此将索引分成几部分:)


由于在GROUP CONCAT中遇到max-length问题,最简单的方法是使用MVA查询。

查看文档http://sphinxsearch.com/docs/current.html#conf-sql-attr-multi

在那里可以定义一个查询来直接获取MVA的数据,避免使用GROUP_CONCAT / GROUP_BY

sql_query = SELECT d.doc_id, ... FROM documents d
sql_attr_multi = uint access_user_id from query; SELECT DISTINCT doc_id, a.user_id FROM documents d
    LEFT JOIN document_category dc ON (dc.doc_id = d.doc_id)
    LEFT JOIN access a ON (a.doc_id = d.doc_id OR a.doc_category_id = dc.category_id)
sql_attr_multi = uint access_user_group_id from query; SELECT DISTINCT doc_id, a.user_group_id FROM documents d
    LEFT JOIN document_category dc ON (dc.doc_id = d.doc_id)
    LEFT JOIN access a ON (a.doc_id = d.doc_id OR a.doc_category_id = dc.category_id)

(可能会对这些查询进行一些优化,但至少应该说明如何开始)