我正在开发一个网络系统,其功能类似于Twitter关注用户列表并将其帖子列为列表的概念。
我提出的简单模型需要join
操作,datastore
无法使用。
class Post(Model):
author = reference to user id
content = text content
class Following(Model):
author = reference to user id
followed_by = reference to user id
频繁的操作是显示用户跟随当前用户的帖子列表(按时间排序)。
使用上述模型,只能分两步完成:
authors = Following.author when Following.followed_by == current_user
posts = Posts with Posts.author in authors
有没有办法更有效地实现这一目标?
答案 0 :(得分:0)
您可以使用structure property存储作者对象中的所有帖子。
这里有一个interesting discussion可能对您选择哪种方法最适合您的用例感兴趣。
答案 1 :(得分:0)
如果稍微更改算法,可以使用单个查询来显示帖子。您可以使用以下实体跟踪特定用户需要显示的帖子:
class DisplayPost(Model):
#parent entity = user for which the post should be displayed
#key ID matches the Post's key ID
posted = datetime # if you want timed ordering in display
expiry = datetime # optional for periodic cleanup jobs
每当作者创建新帖子时,您只需启动任务即可为作者的每个关注者创建此类实体。
每当您需要为用户显示帖子时,您都会进行单个祖先keys_only
查询以获取DisplayPost
键列表:
keys = DisplayPost.query(ancestor=user_key, ...).fetch(keys_only=True)
通过此,您可以获得相应的Post
键列表,并获得get_multi()
操作的帖子,其中包含以下内容:
post_keys = [ndb.Key(Post, key.id()) for key in keys]
posts = ndb.get_multi(post_keys)
这样,您可以在显示帖子时更快地响应,没有join
和IN
(also problematic)操作。更好的可扩展性。支付的价格总是准备DisplayPost
,即使其中一些永远不会被使用(例如,如果相应的用户甚至没有登录)。