2016-12-24 5 views
2

Neo4jでバイナリツリーを作成する必要があります。私は2つのCSVを作成することから始まりました.1つは頂点用、もう1つはエッジ用です。次にツリー全体を作成するために2つのクエリを起動しました。CSVからロードしてバイナリツリーを作成する

1つのクエリでツリー全体を作成できると思っていました。 CSV私は開始場所からこのです:

"parent","child_1","child_1_attr1","child_1_attr2","edge_1_attr1","edge_1_attr2","child_2","child_2_attr1","child_2_attr2","edge_2_attr1","edge_2_attr2" 
"vertex_1","vertex_2","2","5","4","1","vertex_3","5","3","2","2" 
"vertex_2","vertex_4","3","5","2","3","vertex_5","4","4","4","3" 
"vertex_3","vertex_6","2","1","2","4","vertex_7","2","2","5","5" 
"vertex_4","vertex_8","4","4","4","5","vertex_9","2","3","2","5" 
"vertex_5","vertex_10","1","1","3","3","vertex_11","1","3","2","3" 
"vertex_6","vertex_12","3","1","1","1","vertex_13","1","2","5","1" 
"vertex_7","vertex_14","4","2","2","1","vertex_15","2","5","4","3" 

は、その後、私はこのクエリを試してみました:

LOAD CSV WITH HEADERS FROM 'file:///Prova1.csv' AS line 
Match (p:Vertex {name: line.parent}) 
Create (c1:Vertex {name: line.child_1, attr1: line.child_1_attr1, attr2: line.child_1_attr2}) 
Create (c2:Vertex {name: line.child_2, attr1: line.child_2_attr1, attr2: line.child_2_attr2}) 
Create (p)<-[:EDGE {attr1: line.edge_1_attr1, attr2: line.edge_1_attr2}]-(c1) 
Create (p)<-[:EDGE {attr1: line.edge_2_attr1, attr2: line.edge_2_attr2}]-(c2) 

私は手動で最初の頂点を作成し、私はこのクエリを実行しますが、これだけのクエリの前に結果はVertices 1,2,3の作成です。 これは親(これは常に作成済みです)と一致し、次に2つの子を作成し、次にこれらの2つの子を父に接続する必要があります。私を助けることができる

答えて

1

実行の見方は、行/行ごとにすべてのCypherコードを実行し、終了するまで次の行/行に対してこれを繰り返す可能性があります。これは間違っています。

Match (p:Vertex {name: line.parent})

が実行されます。

代わりに、個々のサイファーの動作は、次のサイファー操作はこれはあなたのマッチ操作を意味

など、すべての行に対して実行されます、すべての行に対して実行されますあなたのCSV内のすべての行に同時に表示され、次の操作(すべての行に作用するCREATE)などに進むだけです。

最初の頂点を手動で作成し、その頂点だけが一致すると述べたので、CREATE文がまだ実行されていないため、CSV内の他のすべての行でMATCHが失敗します存在しない。これは、2つの頂点だけが作成されることを意味します。

CSVデータをインポートして最初にすべてのノードを作成してから、すでに作成されたノードとのマッチングと関連する関係を作成するためのCSV処理を別々に行うのがよいでしょう。

しかし、すべての目標を1つの目標で作成したい場合は、さまざまな場所でMERGEを使用することをお勧めしますが、MERGEの動作を完全に理解していないと難しいです一致するものが見つからない場合はCREATE)、またはCypherの実行方法(この場合)を完全には理解できません。

また、すべてのプロパティではなく、一意のノード値に従ってMERGEを行い、残りのプロパティを設定することもできます。特に、グラフのサイズが大きくなるにつれて、関連するラベル/プロパティに一意の制約またはインデックス(適切なもの)を持たせると、実行の高速化に役立ちます。

このクエリが機能する場合があります。この1つは働く

LOAD CSV WITH HEADERS FROM 'file:///Prova1.csv' AS line 
MERGE (p:Vertex {name: line.parent}) 
MERGE (c1:Vertex {name: line.child_1}) 
SET c1.attr1 = line.child_1_attr1, c1.attr2 = line.child_1_attr2 
MERGE (c2:Vertex {name: line.child_2}) 
SET c2.attr1 = line.child_2_attr1, c2.attr2 = line.child_2_attr2 
Create (p)<-[:EDGE {attr1: line.edge_1_attr1, attr2: line.edge_1_attr2}]-(c1) 
Create (p)<-[:EDGE {attr1: line.edge_2_attr1, attr2: line.edge_2_attr2}]-(c2) 

理由は、時間によって、あなたの非常に最初のMERGEは、あなたのグラフのすべての親ノードを作成していますすべての親ノード、(というか、親となるノード)のために完了したことです。

あなたの子ノードのMERGEに達すると、すでに作成されたノードがグラフに表示されます。その時点で作成される唯一の新しいノードは、葉ノードです。あなたの最初のMERGEによって作成されました。それらは他のノードの親ではなく、CSVの親の列には表示されません。

+0

最初に、Cypherコードの実行の詳細な説明をありがとう、私は大学プロジェクトのために自分自身のNeo4jを学んでいるので、非常に便利です。このような簡単な言葉で説明するのは難しいです。 –

+0

ところで、数日前、私はツリーを1つのクエリで作成することができました。このような小さなツリーの場合は機能します。実際には、少なくとも2百万のノードを持つツリーを管理する必要があり、この条件では2つのCSV(ノード用とエッジ用)を持つ2Mノードツリーの作成を改善するためにこの方法を検討していました300秒かかる(汎用ノートブックで 'USING PERIODIC COMMIT'を使用)。 クエリ「USING PERIODIC COMMIT」が機能すると思いますか?そして、このクエリが実際に作成時間を改善できると思いますか? –

+0

PERIODIC COMMITを使用すると、インポートのパフォーマンスが向上するはずです。Vertex(名前)(または名前が頂点に固有でない場合は少なくともインデックス)に一意の制約が必要です。ノードに1つとエッジに2つのCSVを使用する場合は、関係CSVで頂点にMERGEの代わりにMATCHを自由に使用でき、ノード間の関係自体に対してCREATEを使用するとパフォーマンスが向上します。 – InverseFalcon

0

何らかの理由で、インポートクエリが機能しないのは、親と最初に一致してからノードとリレーションシップを作成するためです。私は、クエリをこのように変更され、それが今取り組んでいる:

LOAD CSV WITH HEADERS FROM 'file:///test.csv' AS line 
CREATE (c1:Vertex {name: line.child_1, attr1: line.child_1_attr1, attr2: line.child_1_attr2}), 
     (c2:Vertex {name: line.child_2, attr1: line.child_2_attr1, attr2: line.child_2_attr2}) WITH c1,c2, line 
MATCH (p:Vertex {name:line.parent}) CREATE (p)<-[:EDGE {attr1: line.edge_1_attr1, attr2: line.edge_1_attr2}]-(c1), 
     (p)<-[:EDGE {attr1: line.edge_2_attr1, attr2: line.edge_2_attr2}]-(c2) 

をですから、最初のノードを作成してから親に一致すると、クエリが動作している関係を作成する場合。結果は以下のようになります。

enter image description here

が、私はそれが動作しない理由を私は本当に理解していないので、それが動作していない理由を見つけるためにあなたのクエリに調査します。

+0

これは私がいくつかの失敗後に書くことができたものです。なぜ私のクエリがうまくいかないのかの解説は次の回答にあります:) –

0
foreach (num in range(1,15) | 
merge (parent:Node {number: num}) 
merge (left:Node {number: num + num}) 
merge (right:Node {number: num + num + 1}) 
merge (left)<-[:LEFT]-(parent)-[:RIGHT]->(right) 
) 

説明: これは、31個のノードを持つ完璧なバイナリツリー構造を作成します。次に、対応する番号のついた各ノードにプロパティを見つけて追加するために、同じ番号をCSVに含めることができます。

最初の(ルートまたは最上位のノード)に値1の数値プロパティを含める場合、後続の各ノードの数値を1ずつ増やします(左から右、上から下へ)。各ノードの左の子が親の番号+番号の数値を持ち、右の子が数字+数字+ 1である便利な数学的関係。

関連する問題