2016-09-19 42 views
0

我有一個問題,似乎很適合圖形數據庫,但我不確定應用它的最佳方法。如何使用圖形數據庫進行信譽擴散?

首先有一組對象可以有定向鏈接(數千萬個,典型的鏈接輸入/輸出數量是每個對象幾千個)。然後,每個對象都可以從潛在的非常大量的用戶(也有數千萬)中累積聲譽(認爲upvotes,karma等)。

棘手的部分是,每當用戶調整對象的聲譽,我想基於一些相當複雜的規則,以更新其所有的鏈接對象的聲譽(可能超越一級)。

在SQL中,這將是這個樣子:

CREATE TABLE objects (id INTEGER PRIMARY KEY); 
CREATE TABLE object_links (from_object_id INTEGER, to_object_id INTEGER); 
CREATE TABLE users (id INTEGER PRIMARY KEY); 
CREATE TABLE object_reputations (object_id INTEGER, user_id INTEGER, reputation FLOAT); 

UPDATE 
    object_reputations 
SET 
    object_reputations.reputation = object_reputations.reputation + ... # some formula goes here 
FROM 
    object_reputations 
    INNER JOIN object_links 
     ON object_reputations.object_id = object_links.to_object_id 
WHERE 
    object_links.from_object_id = ...; 

由於這是處理圖形,圖形數據庫似乎是天作之合,但是從Neo4j的/ OrientDB快速閱讀/ Blazegraph/Tinkerpop APIs,我無法弄清楚如何將這個問題映射到他們可以做的事情上。

以Tinkerpop爲例,對象是頂點,對象之間的鏈接是邊(到目前爲止都是好的),聲譽是...?可能是VertexPropetries,但我不確定事情會如何擴展,每個頂點的用戶數量可能與用戶數量一樣多。或者可能聲譽是來自用戶頂點的加權邊緣......這似乎具有不同類型的性能問題。

你可以將這種問題簡單地翻譯成流行的圖形數據庫之一嗎?

+2

在你的SQL例子中,它看起來有點像每個對象有每個用戶的「信譽」。所有用戶的「聲譽」是不一樣的嗎?您能否更好地澄清一下object_reputations在模型中的含義? –

+0

@stephenmallette正確,每個物體對每個用戶都有不同的聲望。並非所有的對象都會在實踐中使用(這取決於聲望在圖表中擴散的程度),但是可能有10%的所有對象都對某個特定用戶有聲望。 –

回答

1

你要總是試圖可視化圖形數據的查詢,而無需使用任何大表(基本上,每個頂點任何超過2點或3的屬性應該被幾乎完全用於數據存儲,查詢不)。如果不能將這些複雜的數據更改爲由頂點之間的較長路徑表示,那麼它可能屬於關係數據庫。

對於像您這樣的基於「透視」的數據,圖表數據庫非常合適。而不是存儲所有的面向用戶的信譽爲對對象屬性的,不過,它們移動到附連到物體獨立的節點,以使得它們可以變成從用戶到對象的路徑的一部分。

所以,你必須爲用戶頂點,該對象的頂點,並且提供一個邊緣到第三頂點的ObjectReputation。每個對象都有幾個相鄰的對象聲明頂點(每個用戶對應一個對象),但沿着從任何用戶到任何對象的邊緣只有一條路徑。爲了找到相關ObjectReputations,你可以沿着邊緣從用戶的瀏覽對象,沿着對象之間的邊緣瀏覽,然後導航從這些對象通過回頂點UserReputation到原來的用戶。

neo4j的Cypher支架的查詢語言,它會是這個樣子:

MERGE (u:User {id:1}) 
MERGE (o:Object {id:2}) 
MERGE (u) - [:KNOWS] -> (ur:ObjectReputation) - [:KNOWS] -> (o) 
SET ur.score = 100 
MATCH (o) - [:RELATED_TO*] - (:Object) <- [:KNOWS] - (related_ur:ObjectReputation) <- [:KNOWS] - (u) 
SET related_ur.score = related_ur.score * 1.2 
2

我會說,這真的取決於如何想查詢你的數據。信譽也可以是頂點,如果它具有有限數量的值並且值在用戶之間重複。例如,如果它是一個1-10的數字,那麼我們可以讓所有名譽爲7的用戶鏈接到這個頂點。此模型將允許您從頂點開始查詢,並輕鬆找到具有該聲譽的所有用戶。使用Gremlin,它會是這樣的。

g.V().has(label,"reputation").has("reputation","7").in() 

這將返回鏈接到名譽爲「7」的信譽頂點的所有頂點。

或者,您也可以聲譽作爲屬性,並且您可以查找具有此類屬性的所有頂點。

g.V().has("reputation","7") 

數量的屬性不應該是一個問題。泰坦建議你索引你想查詢的屬性,這可以提高查找的效率

+0

Upvoted因爲我同意結構的簡單性。我要說的唯一的一點是,我認爲你不應該把聲望作爲每個頂點的屬性。相反,你應該擁有特定的聲望頂點(就像你在這個答案的第一部分所做的那樣)。原因是這個問題指定了聲譽需要被改變,並且更容易(大規模地)將邊修改爲頂點而不是更改頂點本身。 –

相關問題