Google Appengine数据存储上的层次结构优化

我使用看起来像这样的模型将数据存储在数据存储中的分层数据:

class ToolCategories(db.Model):  
   name = db.StringProperty()  
   parentKey = db.SelfReferenceProperty(collection_name="parent_category")  
   ...  
   ...  

我想打印保存层次结构的所有类别名称,例如以下面的形式表示:

--Information Gathering  
----OS Fingerprinting  
----DNS  
------dnstool  
----Port Scanning   
------windows  
--------nmap  
----DNS3  
----wireless sniffers  
------Windows  
--------Kismet  

为了实现上述目的,我使用了反向引用功能的简单递归:

class GetAllCategories (webapp.RequestHandler) :


        def RecurseList(self, object, breaks) :
                output = breaks + object.name + "</br>"
                for cat in object.parent_category:
                        output = output + self.RecurseList(cat, breaks + "--")

                return output



        def get (self) :
                output = ""
                allCategories = ToolCategories.all().filter(' parentKey = ', None)
                for category in allCategories :
                        output = output + self.RecurseList(category, "--")

                self.response.out.write(output)

由于我对App引擎编程非常陌生(自从我开始编写代码几乎没有3天),我不确定这是从Datastore访问角度来看最合适的方式来完成所需的工作。

这是最好的方法吗? 如果不是什么?


你有一个非常合理的方法! 我的主要警告是与GAE很少有关系,并且与Python很多: 不要使用++=创建字符串。 相反,你要制作一个字符串片断列表(带有appendextend或list comprehensions&c),当你完成所有工作时,你可以用''.join(thelist)之类的方式加入最后的字符串结果。 尽管最近的Python版本努力优化++=循环的本质O(N squared)性能,但最终总是会在构建字符串列表的过程中更好,并且''.join它们在最后!


您的方法的主要缺点是,因为您使用“邻接列表”方式来表示树,所以必须为树的每个分支执行一次数据存储查询。 数据存储查询相当昂贵(每个160ms左右),因此构建树,特别是如果它很大,可能会相当昂贵)。

还有另外一种方法,它本质上是数据存储为表示实体组所采用的一种方法:不是仅仅存储父键,而是使用ListProperty存储整个祖先列表:

class ToolCategories(db.Model):
  name = db.StringProperty()
  parents = db.ListProperty(db.Key)

然后,为了构建树,您可以在一个查询中检索整个事物:

q = ToolCategories.all().filter('parents =', root_key)
链接地址: http://www.djcxy.com/p/57817.html

上一篇: Hierarchy Optimization on Google Appengine Datastore

下一篇: Unable to read cookies