2016-05-14 18 views
2

私はチェストーナメントのシンプルなモデルを持っています。それは5人のプレイヤーがお互いにプレイしています。Neo4jグラフの余分な双方向関係を削除する

enter image description here

グラフは、一般的に細かいですが、さらに検査時に、あなたは両方のセット
Guy2対Guy1は、Guy5


Guy4を持っていることを見ることができます:グラフは次のようになります冗長な関係。

問題は、これらのマッチ(したがって、これは、基礎となるCSVデータ品質の問題である意味で)の各々に対して外来相補的な行があるデータには明らかである。

enter image description here

私は手でこれらの行をきれいにすることができましたが、実際のデータセットは何百万行もあります。だから私は、私はCQLを使用して、2つのいずれかの方法でこれらの関係を削除する可能性がどのように思ったんだけど:

1)

2最初の場所

内の余分な関係に読まないでください)先に行くと、余分なを作成します関係を削除しますが、後で削除します。

これに関するアドバイスをありがとうございます。

私が使用しているコードは、このです:

/ Here, we load and create nodes 

LOAD CSV WITH HEADERS FROM 
'file:///.../chess_nodes.csv' AS line 
WITH line 
MERGE (p:Player { 
    player_id: line.player_id 
}) 

ON CREATE SET p.name = line.name 
ON MATCH SET p.name = line.name 

ON CREATE SET p.residence = line.residence 
ON MATCH SET p.residence = line.residence 

// Here create the edges 

LOAD CSV WITH HEADERS FROM 
'file:///.../chess_edges.csv' AS line 
WITH line 
MATCH (p1:Player {player_id: line.player1_id}) 
WITH p1, line 
OPTIONAL MATCH (p2:Player {player_id: line.player2_id}) 
WITH p1, p2, line 
MERGE (p1)-[:VERSUS]->(p2) 
+0

これはあなたの問題とは直接関係しませんが、これらのクエリには無関係の節がたくさんあります。 1.「ON CREATE blah」/「ON MATCH blah」ペアは、単なる「blah」で置き換えることができます。 2.「WITH」節はどの目的にも役立ちません。削除することができます。 – cybersam

+0

#1の場合、どのような構文が適していますか? –

+0

'MERGE'が新しいノードを作成したか既存のノードにマッチしたかにかかわらず、まったく同じ' SET'演算を実行したいので、 'ON MATCH'と' ON create'をまったく使用しないでください。 2つの異なる 'SET'操作を直接実行してください:' SET p.name = line.name、p.residence = line.residence'。 – cybersam

答えて

7

グラフに任意の値や体重を追加しないと、あなたがこの余分な関係を必要としないことは明らかです。

ドキュメントに記載されているにもかかわらず、ほとんど認識されていないものがあります。

MERGEは、undirectedの関係で使用することができます。ネオ4jはあなたのために一方向を選択します(グラフ内の実体関係を指示する必要があります)。

ドキュメントの参照:http://neo4j.com/docs/stable/query-merge.html#merge-merge-on-an-undirected-relationship

たとえば、次のステートメントを使用して、あなたが最初の時間のためにそれを実行する場合:

MATCH (a:User {name:'A'}), (b:User {name:'B'}) 
MERGE (a)-[:VERSUS]-(b) 

が存在しないとそれは関係が作成されます。ただし、2回目に実行すると、変更や作成は行われません。

私はあなたの問題を解決するだろうと思うので、あなたはグラフをきれいにするために、前もってデータを掃除したり、後でスクリプトを実行したりする必要がないでしょう。

+0

すべてのプレイヤーがお互いにプレイしているわけではありません(たとえば、グラフを見るとGuy3とGuy5が実際にはプレイしないことがわかります)。このコードは、存在しない一致を作成したのでしょうか? –

+0

あなたのedges.csvファイルに、Guy3とGuy5との間の関係を表す行がない場合、それは作成されません。 –

+0

ああ、私はあなたが意味するものを見ています。マッチ(p1:プレーヤー{player_id:line.player1_id})、(p2:プレーヤー{player_id:line.player2_id}) マージ(p1) - [:対戦] - (p2) 'のようなものです。私は前に見たこの警告を受け取ります: 'このクエリは、切断されたパターンの間にデカルト積を作ります。 ' –

2

私は選手たちとは別の試合についての追跡の詳細を有効にするので、

(x:Player)-[:MATCH]->(m:Match)<-[:MATCH]-(y:Player) 

のように「一致」ノードを作成することをお勧めしたいです。

あなたはプレイヤーが試合そのものは異なる対戦追跡する必要がある場合は、

(x:Player)-[:HAS_PLAYED]->(pair:HasPlayed)<-[:HAS_PLAYED]-(y:Player) 

は、トリックを行うだろう。

+1

私は一致についての情報を保持するエッジは、あなたのスキーマの変更を推奨していますか?私はそれをそのままにして、冗長性を取り除くことを好むでしょう。 –

+0

Tim - Matchノードを持つこと(または興味深い議論のために少なくとも作ること)は良い提案かもしれませんが、これは冗長な関係を削除するというコアな問題に答えるものではないことを示唆しています。 –

+0

すべての点を尊重しながらも、冗長な関係、つまりスキーマの構成方法が重要な問題です。 –

2

スキーマが滞在している場合など-であり、唯一の要件は、トリックを行う必要があり、その後

MATCH (p1:Player)-[r1:VERSUS]->(p2:Player)-[r2:VERSUS]->(p1) 
DELETE r2 

、冗長な関係を削除することです。これにより、双方向のVERSUS関係を持つすべてのp1、p2ノードが検索され、それらのいずれかが削除されます。

+0

一致する(p1:Player) - [r1:VERSUS] - >(p2:Player) - [r2:VERSUS] - >(p1) ここで、id(p1) nmervaillie

関連する問題