0

我们有一个用例,用户必须能够搜索仅在他们有权访问的组中可用的内容。搜索必须跨越他们有权访问的所有组。

一些细节:一个组有很多帖子,一个用户可以访问数百个组和每个组内的数千个帖子。搜索“Foo”应返回名称中包含“Foo”的所有组和他们有权访问的组中的所有帖子,并且内容中包含“Foo”。

我想处理它的方法是在每个文档索引上关联一个 user_id 列表,然后在查询字符串中包含 user_id 以验证用户是否具有访问权限。返回结果后,我们可以在返回结果之前进行额外检查以查看他们是否可以访问内容。

文档索引是这样的:

fields = [
  search.TextField(name="data", value="some searchable stuff"),
  search.AtomField(name="post_id", value="id of post"),
  search.AtomField(name="group_id", value="id of group"),
  search.AtomField(name="user_id", value=user_id_1),
  search.AtomField(name="user_id", value=user_id_2),
  #.... add the thousand other users who have access to the group (done in loop)     
]

#then query run a user 123 would be as follows:
results = index.search("data = Foo AND user_id = 123")

我对上述方法的担忧:每个订阅组的新用户都需要重新索引搜索索引以在每个文档中包含他们的 user_id。

有没有更好的方法来处理这个用例?

谢谢罗伯

4

1 回答 1

0

你的问题没有简单的答案。您需要计划 (a) 典型用例和 (b) 极端情况。

如果一个典型的用户属于 1-3 个组,那么通过 group_id 搜索可能是最好的解决方案。您将进行 1-2 次额外搜索,但您无需在每次用户加入或退出组时重新索引每个文档,这非常昂贵。

对于极端情况,您可以有一个单独的实现。如果一个用户属于 X 个以上的组,那么检索所有匹配关键字的结果,然后通过 group_id 过滤它们可能会更有效。

另一种方法是始终检索所有结果,而不考虑 group_id/user_id,并将它们存储在 Memcache 中。然后你可以在内存中过滤它们。

用户倾向于使用相同的关键词进行搜索——根据你的语料库,1% 的词可能占到 99% 的搜索。如果您有很多用户 - 并且缓存足够大 - 您将获得大量缓存命中。请注意,1GB 的缓存可以容纳数万甚至数十万条查询结果。这种方法的另一个优点是它加快了所有查询,尤其是短语或多关键字搜索。

于 2016-09-08T20:02:57.937 回答