2011-07-23 15 views
1

私は100個の頂点を持つ有向グラフ、重み付き完全グラフを持っています。頂点はムービーを表し、エッジは2つのムービー間のプリファレンスを表します。ユーザーが自分のサイトにアクセスするたびに、5つの頂点のセットを照会してユーザーに表示します(そのセットは頻繁に変更されます)。これらの頂点をA、B、C、D、Eと呼ぶことにする。ユーザはそれらを注文する(すなわち、これらの映画を大部分のお気に入りから最も好きなものにランク付けする)。例えば、彼は私がその後、次のようにグラフを更新する必要がD、B、A、C、E、それらを注文することがありますGAEデータストアに有向グラフ、重み付き完全グラフを格納

Graph[D][B] +=1 
Graph[B][A] +=1 
Graph[A][C] +=1 
Graph[C][E] +=1 

をので、カウントグラフ[V1] [V2]はどのように多くのユーザーを表す終わります(ムービー)V2の直上にランク付け(ムービー)します。データが収集されるとき、私はあらゆる種類のオフライングラフ分析を行うことができます。グラフのシンクとソースを見つけて、最も好きな映画と最も好きでない映画を特定します。

問題は次のとおりです。データストアに指示グラフ、加重グラフ、完全グラフを保存するにはどうすればよいですか?

class Vertex(db.Model): 
    name = db.StringProperty() 

class Edge(db.Model): 
    better = db.ReferenceProperty(Vertex, collection_name = 'better_set') 
    worse = db.ReferenceProperty(Vertex, collection_name = 'worse_set') 
    count = db.IntegerProperty() 

しかし、私はこれを見る問題は、私はの線に沿って4つの別々の醜いクエリを作成しなければならないということである:明白な答えはこれですその後、私は(更新し、配置する必要があり

edge = Edge.all().filter('better =', vertex1).filter('worse =', vertex2).get() 

)5番目のクエリの新しいエッジ。

より効率的に(少ないクエリ)が、ハック実装は辞書をシミュレートするために、リストのペアを使用した、この1のようになります。

class Vertex(db.Model): 
    name = db.StringProperty() 
    better_keys = db.ListProperty(db.Key) 
    better_values = db.ListProperty(int) 

だから、AがBよりも優れていると言ってスコアを追加するために、私は次のようになります:

index = vertexA.index(vertexB.key()) 
vertexA.better_values[index] += 1 

もっと効率的な方法がありますか?

+0

グラフはこのサイズで固定されていますか?全体を単一のエンティティに格納することはできませんか? –

答えて

1

私は私の質問で提案した最初のデザインを少し修正して自分の問題を解決しました。

私は自分のキー名を設定できる引数key_nameについて知りました。だから私は、新しいエッジを作成するたびに、私は、コンストラクタに次の引数を渡す:

key_name = vertex1.name + ' > ' + vertex2.name 

その後、代わりにこのクエリを複数回実行するので:

edge = Edge.all().filter('better =', vertex1).filter('worse =', vertex2).get() 

私はので、簡単にエッジを取得することができます私は彼らの鍵を構築する方法を知っています。 Key.from_path()メソッドを使用して、エッジを参照するキーのリストを作成します。私はその後、1つのクエリ内のすべてのオブジェクトを取得するには、キーのリストを渡す

db.Key.from_path('Edge', vertex1.name + ' > ' + vertex2.name) 

:各キーは、これを行うことによって得られます。