我正在开发一个网络系统,其中的功能类似于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
有没有办法更有效地实现这一目标?
您可以使用结构属性来存储作者对象中的所有帖子。
这里有一个有趣的讨论,您可以选择哪种方法最适合您的用例可能会很有趣。
如果您稍微更改算法,则可以使用单个查询来显示帖子。您可以使用以下实体跟踪需要为特定用户显示哪些帖子:
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
(也有问题(的操作。更好的可扩展性。要付出的代价总是 准备DisplayPost
,即使其中一些永远不会被使用(例如,如果相应的用户甚至没有登录(。