Оптимизация иерархии в хранилище данных Google Appengine - PullRequest
4 голосов
/ 21 июня 2009

У меня есть иерархические данные, хранящиеся в хранилище данных с использованием модели, которая выглядит следующим образом:

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)

Поскольку я очень новичок в программировании движка приложений (вряд ли 3 дня с тех пор, как я начал писать код), я не уверен, является ли это наиболее оптимизированным способом с точки зрения доступа к Datastore для выполнения желаемой работы.

Это лучший способ? если не то, что есть?

Ответы [ 2 ]

4 голосов
/ 21 июня 2009

Основным недостатком вашего подхода является то, что, поскольку вы используете способ представления деревьев с помощью списка смежности, вы должны выполнить один запрос к хранилищу данных для каждой ветви дерева. Запросы к хранилищу данных довольно дороги (около 160 мс каждый), поэтому построение дерева, особенно если оно большое, может быть довольно дорогим).

Существует другой подход, который, по сути, используется хранилищем данных для представления групп сущностей: вместо простого хранения родительского ключа сохраните весь список предков, используя ListProperty:

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

Затем, чтобы построить дерево, вы можете получить всю вещь в одном запросе:

q = ToolCategories.all().filter('parents =', root_key)
2 голосов
/ 21 июня 2009

У вас очень разумный подход! Моим главным предупреждением было бы то, что не имеет ничего общего с GAE, а с Python очень много: не строит строку из кусочков с + или +=. Скорее вы составляете список кусочков строк (с помощью append или extend или списков и т. Д.), И когда вы все закончите, вы объединяете его для получения окончательного результата строки с помощью ''.join(thelist) или подобного. Несмотря на то, что последние версии Python изо всех сил стараются оптимизировать внутреннюю O(N squared) производительность циклов + или +=, в конце концов, вам всегда лучше составлять списки строк по пути и ''.join их увеличивать. в самом конце!

...