2016-09-19 2 views
0

私はグラフデータベースに適しているような問題がありますが、それを適用する最善の方法は不明です。評判拡散にグラフデータベースを使用するには?

第1の方向のリンクを持つことができるオブジェクトのセットがあります(そのうちの何百万の数十は、/アウト数の典型的なリンクは、オブジェクトあたり数千です)。そして、各オブジェクトは潜在的に非常に多数のユーザーからの評判(upvotes、karmaなど)を蓄積することができます(数千万も)。

難しいのは、ユーザーがオブジェクトの評判を調整するたびに、いくつかのかなり複雑なルールに基づいて、すべてのリンクされたオブジェクトの評判を(おそらく第1度を超えて)更新することです。 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 APIを使用しているので、私はどのようにしてこの問題を彼らができることにマップするのかを理解できません。

例としてTinkerpopを使用して、オブジェクトは、オブジェクト間のリンクは(今のところ、すべての良い)エッジの頂点されていると評判がありますか...? VertexPropetriesの可能性はありますが、ユーザーと同じように頂点ごとに多くのプロパティが潜在的にどのように拡大するかはわかりません。あるいは、評判はユーザーの頂点からの重み付けされたエッジです...異なる種類のパフォーマンスの問題があるようです。

あなたは人気のグラフデータベースの一つにこの種の問題の簡単な翻訳を与えることができますか?

+2

SQLの例では、各オブジェクトがユーザーごとに「評判」を持つように見えます。 「評判」はすべてのユーザーにとって同じではありませんか?あなたのモデルでobject_reputationsが何をしているのかを明確にしてください。 –

+0

@stephenmallette修正すると、すべてのオブジェクトはすべてのユーザーに異なる評判を与えます。すべてのオブジェクトが実際にはそうではなく(評判がグラフにどれだけ拡散しているかにもよるが)、すべてのオブジェクトの10%が1つの特定のユーザーにとって評判を持つだろう。 –

答えて

1

あなたは(基本的には、頂点あたり2つのまたは3の特性以上のものを照会していない、データストレージのためにほぼ独占的に使用する必要があります)常に大きなテーブルを使用せずに、グラフのデータクエリを視覚化してみたいです。そのような複雑なデータを頂点間のより長いパスで表現するように変更できない場合は、おそらくリレーショナルデータベースに属しています。あなたのような「視点」に基づくデータでは

は、しかし、グラフデータベースはぴったりです。ただし、ユーザー指向の評判のすべてをオブジェクトとしてプロパティとして格納する代わりに、オブジェクトに関連付けられた別々のノードに移動して、ユーザーからオブジェクトへのパスの一部にすることができます。

だから、あなたは、オブジェクトの頂点をユーザーのための頂点を持ち、それぞれが第三の頂点、ObjectReputationにエッジを持っています。各オブジェクトには、いくつかの隣接するObjectReputation頂点(オブジェクトに関連する各ユーザーごとに1つ)がありますが、任意のユーザーから任意のオブジェクトまでのエッジに沿った単一のパスしかありません。関連するObjectReputationsを見つけるには、UserからObjectまでのエッジに沿って移動し、Objects間のエッジに沿ってナビゲートし、UserReputationの頂点を通って元のUserに戻ることができます。 neo4jのサイファークエリ言語で

が、それはこのようになります:

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") 

プロパティの数は問題ではありません。 Titanは照会するプロパティのインデックスを作成することをお勧めします。

+0

私は構造の簡潔さに同意しているので、Upvoted。私が作る唯一のポイントは、評判をすべての頂点のプロパティにする必要はないと考えていることです。むしろ、特定の評判頂点を持っている必要があります(この回答の最初の部分のように)。その理由は、評判を変更する必要があることを指定することで、頂点を変更するのではなく、エッジを頂点に変更する方が(大規模で)はるかに簡単です。 –

関連する問題