2010-10-23 58 views
3

好的。我正在与GAE合作。我想创造一些这样的:GAE组织数据结构问题

我有类型的“组”,“主题”,“标签”:

  1. 根据需要每一个“组”可以有很多 “主题”

  2. 每个 “主题” 可以根据需要有尽可能多的 “标签”

  3. 每个“组”可以有很多“标签” 需要

它像圈。

现在我有这样的事情:

class TopicGroup(db.Model): 
    value = db.StringProperty(required=True) 

class Topic(db.Model): 
    title = db.StringProperty(required=True) 
    group = db.ReferenceProperty(TopicGroup, 'group', 'topics', required=True) 

class TopicTag(db.Model): 
    topic = db.ReferenceProperty(Topic, 'topic', 'tags', required=True) 
    group = db.ReferenceProperty(TopicGroup, 'group', 'tags', required=True) 
    value = db.StringProperty(required=True) 

但是这是没有好(在我的模型“主题”只能有一个标签,但我NEAD“主题”有尽可能多的标签,需要)

以及我已经有一个裂缝在我的脑海...有没有人谁可以帮助?

回答

5

多对多连接可以实现为连接表(或关系模型)。在下面的溶液中,存在其中容纳了应用于各个GroupsGroupTags)标签的模型,并保持被施加到TopicsTopicTags)标签的模型。

从到Tag引用解耦Tag本身允许你做的事情,比如修改标签的拼写,而无需更新这是Tag应用于每GroupTopic来。

此外,这款机型采用的是AppEngine上在具有其他实体引用它们的实体创建自动反向引用的事实很好的优势。在下面的模型,一组实体将有一个属性叫做topics这是一个查询,将获取所有Topic实体谁是group参考指向Group。类似地,每个GroupGroupsTags模型获得tags属性,该属性给出属于它的所有Tag实体。每个Tag实体都获得一个groupstopics属性,该属性是查询所有赋予给定标记的类型的所有实体的查询,使得通过标记进行搜索(一种非常典型的操作)非常简单。

这是一个非常强大和灵活的方法来建模系统,如你的。

class Group(db.Model): 
    # All of my group-specific data here. 

class Topic(db.Model): 
    title = db.StringProperty(required=True) 
    group = db.ReferenceProperty(Group, collection='topics') 
    # other topic-specific data here. 

class Tag(db.Model): 
    text = db.StringProperty(required=True) 

class GroupTags(db.Model): 
    group = db.ReferenceProperty(Group, collection='tags') 
    tag = db.ReferenceProperty(Tag, collection='groups') 

class TopicTags(db.Model): 
    topic = db.ReferenceProperty(Topic, collection='tags') 
    tag = db.ReferenceProperty(Tag, collection='topics') 
+0

哇... Tnx很多..你救了我的一天:)我刚刚开始与GAE一起工作..所以这对我来说并不困难。无论如何,再次tnx。 – 2010-10-23 17:13:52

2

的解决方案是使用一个db.ListProperty与类型db.Key的。 请参阅:http://code.google.com/appengine/articles/modeling.html(部分多对多)

+1

此方法的主要限制是ListProperty限制为5000个值。而且,执行诸如删除以这种方式引用的对实体的所有引用的操作可能是非常困难的;您需要查询每个列表中具有待删除键的实体,然后更新每个列表。这对于大量的实体来说并不好。 – 2010-10-23 16:12:42

+0

是的,但db.get(a_list)要快得多。所以,这取决于你使用它。如果一个主题可以有超过1米的密钥,那么......但它提供了一点点建议 – sahid 2010-10-23 16:24:06

+0

你在密钥列表上做一个'get'是非常有效的,所以如果系统很少写入并且主要是读取,那么你的解决方案具有重大优势。 – 2010-10-23 16:34:38