我想在搜索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属性。
我需要一些提示来构建索引来过滤掉用户不允许看到的结果(可能有多个索引?)
答案 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)
(可能会对这些查询进行一些优化,但至少应该说明如何开始)