Database Sphinx搜索引擎与访问权限表一起使用

Database Sphinx搜索引擎与访问权限表一起使用,database,sphinx,Database,Sphinx,我想在通过sphinx索引搜索时检查正在查找某些文档的用户的读取权限 例如,我有一个documents表,带有doc\u id、doc\u title和doc\u is\u global。另一方面,我有一个accessprivileges表,其结构如下: 用户id、用户组id、文档id、文档类别id 用户可以分组到具有标识符user\u group\u id的“user\u group”中,文档可以等效为文档类别 访问表可能如下所示: 用户id、用户组id、文档id、文档类别id 1,空,1,空

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

例如,我有一个documents表,带有doc\u id、doc\u title和doc\u is\u global。另一方面,我有一个accessprivileges表,其结构如下:

用户id、用户组id、文档id、文档类别id

用户可以分组到具有标识符user\u group\u id的“user\u group”中,文档可以等效为文档类别

访问表可能如下所示:

用户id、用户组id、文档id、文档类别id

1,空,1,空

零,12,零,32

1,空,空,31

零,10,1,零

用户应仅查找is_global flag设置为1或其用户id或其所属组id具有访问权限的文档

在纯MySQL中,我通过一些连接获得正确的结果,如:

    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使用多个属性创建这种情况,它会返回类似于:

访问用户访问id=(1,4,6,2)访问用户访问id=(1,5,3)

因此,无法检查谁向谁授予了阅读权限。下一个问题是Sphinx只支持每个索引最多4gb的属性


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

您可以用它来索引

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只支持每个索引最多4gb的属性

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

在任何情况下,如果属性太多,则限制为每个索引。因此,将索引切分为以下部分:)


由于在组CONCAT中遇到最大长度的问题,最简单的方法是使用MVA查询

请参阅文档

在这里,您可以定义一个查询来直接获取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)

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

感谢您的回复,您给了我正确的提示。现在我遇到了组concat\u max\u length的问题。在某些情况下,可能是一些文档共享给数千名用户。我认为它将与一个单独的表一起工作,所有数据都存储在这个表中。在OracleDBMS中,我将构建一个带有动态查询的pl/sql过程,并在access_用户表等(包DBMS_sql)上进行迭代,以获取分块数据并将其插入临时表。我也可以用php实现,但我认为这不是最好的主意。你有一个2。提示我如何在mysql上解决这个问题?编辑了答案,加入了使用GROUP_CONCAT.>>的备选方案,因此将索引分为多个部分
如何实现?