按用户限制 GAE 搜索 API 个结果
Limiting GAE Search API results by user
我们有一个用例,用户必须能够搜索仅在他们有权访问的群组中可用的内容。搜索必须跨越他们有权访问的所有组。
一些细节:
一个群组有很多帖子,一个用户可以访问数百个群组和每个群组中的数千个帖子。
搜索 "Foo" 应该 return 所有名称中带有 "Foo" 的组和所有帖子,在他们有权访问的组中,并且内容中具有 "Foo"。
我想到的处理方式是在每个文档索引上关联一个 user_id 的列表,然后在查询字符串中包含 user_id 以验证用户有使用权。一旦结果被 returned,我们可以进行额外的检查,以确保他们在 returning 结果之前可以访问内容。
文档索引是这样的:
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。
有没有更好的方法来处理这个用例?
谢谢
罗布
您的问题没有简单的答案。您需要针对 (a) 典型用例和 (b) 极端情况进行规划。
如果一个典型的用户属于 1-3 个组,按 group_id 搜索可能是最好的解决方案。您将进行 1-2 次额外的搜索,但您不需要在每次用户加入或退出群组时都为每个文档重新编制索引,这非常昂贵。
您可以针对极端情况单独实施。如果用户属于多于 X 个组,检索所有匹配关键字的结果,然后按 group_id.
筛选可能更高效
另一种方法是始终检索所有结果,而不考虑 group_id/user_id,并将它们存储在 Memcache 中。然后你可以在内存中过滤它们。
用户倾向于使用相同的关键词进行搜索 - 根据您的语料库,1% 的词可能占搜索的 99%。如果您有很多用户 - 以及足够大的缓存 - 您将获得很多缓存命中。请注意,1GB 的缓存可以容纳数万甚至数十万条查询结果。这种方法的另一个优点是它可以加快所有查询的速度,尤其是短语或多关键字搜索。
我们有一个用例,用户必须能够搜索仅在他们有权访问的群组中可用的内容。搜索必须跨越他们有权访问的所有组。
一些细节: 一个群组有很多帖子,一个用户可以访问数百个群组和每个群组中的数千个帖子。 搜索 "Foo" 应该 return 所有名称中带有 "Foo" 的组和所有帖子,在他们有权访问的组中,并且内容中具有 "Foo"。
我想到的处理方式是在每个文档索引上关联一个 user_id 的列表,然后在查询字符串中包含 user_id 以验证用户有使用权。一旦结果被 returned,我们可以进行额外的检查,以确保他们在 returning 结果之前可以访问内容。
文档索引是这样的:
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。
有没有更好的方法来处理这个用例?
谢谢 罗布
您的问题没有简单的答案。您需要针对 (a) 典型用例和 (b) 极端情况进行规划。
如果一个典型的用户属于 1-3 个组,按 group_id 搜索可能是最好的解决方案。您将进行 1-2 次额外的搜索,但您不需要在每次用户加入或退出群组时都为每个文档重新编制索引,这非常昂贵。
您可以针对极端情况单独实施。如果用户属于多于 X 个组,检索所有匹配关键字的结果,然后按 group_id.
筛选可能更高效另一种方法是始终检索所有结果,而不考虑 group_id/user_id,并将它们存储在 Memcache 中。然后你可以在内存中过滤它们。
用户倾向于使用相同的关键词进行搜索 - 根据您的语料库,1% 的词可能占搜索的 99%。如果您有很多用户 - 以及足够大的缓存 - 您将获得很多缓存命中。请注意,1GB 的缓存可以容纳数万甚至数十万条查询结果。这种方法的另一个优点是它可以加快所有查询的速度,尤其是短语或多关键字搜索。