Google App Engine上的高度可扩展标签(Python)

gor*_*uad 5 python tags google-app-engine high-load microblogging

我有很多(例如)帖子,标有一个或多个标签.可以创建或删除帖子,并且用户也可以对一个或多个标签进行搜索请求(与逻辑AND结合).我想到的第一个想法是一个简单的模型

class Post(db.Model):
  #blahblah
  tags = db.StringListProperty()
Run Code Online (Sandbox Code Playgroud)

创建和删除操作的实现是显而易见的.搜索更复杂.要搜索N个标签,它将执行N GQL查询,例如"SELECT*FROM Post WHERE tags =:1"并使用游标合并结果,并且它具有糟糕的性能.

第二个想法是分离不同实体中的标签

class Post(db.Model):
    #blahblah
    tags = db.ListProperty(db.Key) # For fast access

class Tag(db.Model):
    name = db.StringProperty(name="key")
    posts = db.ListProperty(db.Key) # List of posts that marked with tag
Run Code Online (Sandbox Code Playgroud)

它通过密钥从db获取标签(比通过GQL快得多)并将其合并到内存中,我认为此实现具有比第一个更好的性能,但是非常频繁可用的标签可以超过允许单个数据存储对象的最大大小.还有另外一个问题:数据存储区只能修改一个单个对象~1 /秒,因此对于频繁使用的标记,我们也存在修改延迟的瓶颈.

有什么建议?

Sin*_*ion 0

可能的解决方案是采用第二个示例,并以允许对较大集合进行有效查询的方式对其进行修改。我想到的一种方法是对单个标签使用多个数据库实体,并以您很少需要获得多个组的方式对它们进行分组。如果默认排序顺序(我们将其称为唯一允许的排序顺序)是按过后日期排序,则按该顺序填充标签组实体。

class Tag(db.Model):
    name = db.StringProperty(name="key")
    posts = db.ListProperty(db.Key) # List of posts that marked with tag
    firstpost = db.DateTimeProperty()
Run Code Online (Sandbox Code Playgroud)

在向组添加或删除标签时,请检查该组中有多少帖子,如果您添加的帖子会使该帖子的数量超过(例如 100),请将其分成两个标签组。如果您要删除帖子以使该群组的帖子少于 50 个,请从上一个或下一个群组中窃取一些帖子。如果相邻组之一也有 50 个帖子,则将它们合并在一起。当按标签列出帖子(按发布日期顺序)时,您只需要获取少数组。

这并不能真正解决高需求标签问题。

想一想,插入更具推测性可能还可以。获取最新的标签组条目,合并它们并放置一个新的标签组。交易的滞后实际上可能不是一个真正的问题。