4

次のようなモデルを使用して、データストアに階層データを格納しています。

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 Engine プログラミングに非常に慣れていないため (コードを書き始めてからわずか 3 日)、これがデータストア アクセスの観点から最も最適化された方法で目的のジョブを実行できるかどうかはわかりません。

これが最善の方法ですか?そうでない場合は何ですか?

4

2 に答える 2

4

このアプローチの主な欠点は、ツリーを表す「隣接リスト」の方法を使用しているため、ツリーのブランチごとに 1 つのデータストア クエリを実行する必要があることです。データストア クエリはかなりコストがかかる (それぞれ約 160 ミリ秒) ため、特にツリーが大きい場合は、ツリーの構築にかなりのコストがかかる可能性があります)。

エンティティ グループを表すためにデータストアが本質的に採用する別のアプローチがあります。親キーを格納するだけでなく、ListProperty を使用して先祖のリスト全体を格納します。

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

次に、ツリーを構築するために、1 つのクエリで全体を取得できます。

q = ToolCategories.all().filter('parents =', root_key)
于 2009-06-21T12:34:17.907 に答える
2

あなたは非常に合理的なアプローチをしています!私の主な警告は、GAE とはほとんど関係がなく、Python とは多くの関係があるということ+です+=。むしろ、文字列の断片のリストを作成し ( appendorextendまたはリスト内包表記 &c を使用)、すべてが完了したら、最終的な文字列結果を得るためにそれを結合します''.join(thelist)。最近の Python バージョンでは、 orループの本質的なO(N squared)パフォーマンスを最適化するために懸命に努力していますが、最終的には、途中で文字列のリストを作成し、最後にそれらを ing する方が常に良いでしょう!++=''.join

于 2009-06-21T05:00:24.667 に答える