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

我有很多(例如)帖子,标有一个或多个标签。可以创建或删除帖子,并且用户也可以对一个或多个标签进行搜索请求(与逻辑AND结合)。 我想到的第一个想法是一个简单的模型
class Post(db.Model):
  #blahblah
  tags = db.StringListProperty()
创建和删除操作的实现是显而易见的。搜索更复杂。要搜索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
它通过密钥从db获取标签(比通过GQL快得多)并将其合并到内存中,我认为此实现具有比第一个更好的性能,但是非常频繁可用的标签可以超过允许单个数据存储对象的最大大小。还有另外一个问题:数据存储区只能修改一个单个对象~1 /秒,因此对于频繁使用的标记,我们也存在修改延迟的瓶颈。 有什么建议?     
已邀请:
进一步尼克的质疑。如果是逻辑AND,则在查询中使用多个标签。使用tags = tag1 AND tags = tag2 ...在单个查询中设置成员资格是数据存储区的闪亮功能之一。您可以在一个查询中实现结果。 http://code.google.com/appengine/docs/python/datastore/queriesandindexes.html#Properties_With_Multiple_Values     
可能的解决方案是采用您的第二个示例,并以允许在较大集合上进行高效查询的方式对其进行修改。我想到的一种方法是为单个标签使用多个数据库实体,并以这样的方式对它们进行分组,因为您很少需要获得多个组。如果默认排序顺序(我们只允许将其称为唯一允许的顺序)是按日期排序,则按顺序填充标记组实体。
class Tag(db.Model):
    name = db.StringProperty(name="key")
    posts = db.ListProperty(db.Key) # List of posts that marked with tag
    firstpost = db.DateTimeProperty()
向组中添加或删除标签时,请检查该组中有多少帖子,如果您要添加的帖子会使帖子超过100个帖子,则将其拆分为两个标签组。如果您要删除帖子以使该组的帖子少于50个,则从前一组或下一组中窃取一些帖子。如果其中一个相邻组也有50个帖子,则将它们合并在一起。按标签列出帖子(按照日期后的顺序),您只需要获得少数几个组。 这并不能真正解决高需求标签问题。 考虑到这一点,插入可能更具有推测性。获取最新的标记组条目,合并它们并放置一个新的标记组。事务中的滞后实际上可能不是一个真正的问题。     

要回复问题请先登录注册