2011-07-23 52 views
1

我有一個帶有100個頂點的定向加權完整圖形。頂點表示電影,邊緣表示兩部電影之間的偏好。每次用戶訪問我的網站時,我都會查詢一組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]最終代表多少用戶排名(電影)V1正上方(電影)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() 

然後我需要更新,並把( )第五個查詢中的新邊。

更有效(較少的查詢),但哈克實施將是這一場,它採用雙列表來模擬一個字典:

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()方法,我構造了一個引用邊的關鍵字列表。每個按鍵都被這樣獲得的:

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

我再通過按鍵的該列表以獲得在一個查詢中的所有對象。