用户

时间:2016-09-08 16:31:54

标签: google-app-engine gae-search

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

一些细节: 一个群组拥有许多帖子,用户可以访问每个群组中的数百个群组和数千个帖子。 搜索“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。

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

由于 罗布

1 个答案:

答案 0 :(得分:0)

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

如果典型用户属于1-3组,则按group_id搜索可能是最佳解决方案。您将进行1-2次额外搜索,但每次用户加入或退出组时,您都不需要重新索引每个文档,这非常昂贵。

您可以针对极端情况单独实施。如果用户属于多个X组,则检索与该关键字匹配的所有结果可能更有效,然后按group_id过滤它们。

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

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