Cypherを使用してNeo4jでオクトリー構造を作成したいと考えています。各ノードおよび「手動」の関係を作成することなく、これを実装する方法についてCypherを使用してNeo4jで簡単なオクトリー構造を作成する
任意のアイデア:私は、下の図のようなものを作成したいと思いますか?
Cypherを使用してNeo4jでオクトリー構造を作成したいと考えています。各ノードおよび「手動」の関係を作成することなく、これを実装する方法についてCypherを使用してNeo4jで簡単なオクトリー構造を作成する
任意のアイデア:私は、下の図のようなものを作成したいと思いますか?
サイファーだけでも可能ですが、プログラミング言語を使用してneo4jに接続してノードとリレーションシップを作成することができます。例えばPHPで
:CYPHER文は、あなたのNeo4jのインスタンスに接続し、それらの文を実行する必要がある。もちろん、
function create_children($parent){
print "\n$parent: ";
for ($i=0; $i<=7;$i++) {
$node_id = (int) "$parent"."$i";
$children[] = $node_id;
print "$node_id,";
// create children nodes
// CREATE (child:node) SET node_id = $node_id
//create relationship here
// MATCH (parent:node) where node_id = $parent
// CREATE (parent)-[r:parent_of]->(child)
}
return $children;
}
function create_tree ($root, $depth) {
if ($depth ==0) return;
else{
$children = create_children($root);
$depth--;
foreach ($children as $child) {
create_tree($child, $depth);
}
}
}
// MAIN
// CREATE (parent:node) SET node_id=0;
create_tree(0,3);
。
あなたはちょうどCYPHER文をプリントアウトして、ここにネオシェルまたはブラウザ
に貼り付けることができることを行うには方法がわからない場合create_tree(0,2)
出力を実行しているの出力は、親がその8人の子供が続く示しています
0: 00,01,02,03,04,05,06,07,
00: 00,01,02,03,04,05,06,07,
01: 10,11,12,13,14,15,16,17,
02: 20,21,22,23,24,25,26,27,
03: 30,31,32,33,34,35,36,37,
04: 40,41,42,43,44,45,46,47,
05: 50,51,52,53,54,55,56,57,
06: 60,61,62,63,64,65,66,67,
07: 70,71,72,73,74,75,76,77,
それはあなたが事前にその高さがわかっている場合は、ツリーを生成するためのサイファーを使用することができます
を探していたものだなら、私に知らせてください。わかりやすくするために、2分木(分岐係数2)を生成しました。
WITH 0 as root, range(1,2) AS branches
WITH root as root, branches AS l1s, branches AS l2s
UNWIND l1s AS l1
UNWIND l2s AS l2
MERGE (n0:TreeNode {name: root})
MERGE (n1:TreeNode {name: l1})
MERGE (n2:TreeNode {name: l1+"_"+l2})
MERGE (n0)-[:X]->(n1)
MERGE (n1)-[:X]->(n2)
これは、次のツリーになり:
説明:k個のレベルのツリーのために、我々はbranches
変数が回-1をK、および各リストをほどくコピーします。これはデカルト積を生成し、リーフノードを生成する。 kレベルの(完全な)二分木に対して、これは2 ^(k-1)の葉ノードをもたらす。 (これは、8 ^(k-1)レベルのオクツリーにも適用されます)
各レベルの固有の変数名を作成するために、レベルの数をアンダースコアと組み合わせます。 IDSは、次のようなクエリを実行することができます。
WITH 0 as root, range(1,2) AS branches
WITH root as root, branches AS l1s, branches AS l2s
UNWIND l1s AS l1
UNWIND l2s AS l2
RETURN root, l1, l1+"_"+l2
これは、その結果:今
╒════╤═══╤═════════╕
│root│l1 │l1+"_"+l2│
╞════╪═══╪═════════╡
│0 │1 │1_1 │
├────┼───┼─────────┤
│0 │1 │1_2 │
├────┼───┼─────────┤
│0 │2 │2_1 │
├────┼───┼─────────┤
│0 │2 │2_2 │
└────┴───┴─────────┘
我々は、ノードとリレーションシップを作成するだけです、注意を払いながらノードは/エッジは一度だけ作成されます。これは、MERGE
を使用することによって保証されます。 (MERGE
最初はトリッキーに見えるかもしれませんが、good explanationsがあります。)
をあなたは追加のレベルを追加したい場合は、のようなクエリを更新します。
l3s
l3
MERGE (n3:TreeNode {name: l1+"_"+l2+"_"+l3})
MERGE (n2)-[:X]->(n3)
もちろん、ノードに数値を使用することもできます。アンダースコアを追加する代わりに、各ノードに新しい数値「ID」を生成する必要があります。
WITH range(1,2) AS branches
WITH branches AS l1s, branches AS l2s
UNWIND l1s AS l1
UNWIND l2s AS l2
MERGE (n0:TreeNode {number: 0})
MERGE (n1:TreeNode {number: l1})
MERGE (n2:TreeNode {number: 2*l1+l2})
MERGE (n0)-[:X]->(n1)
MERGE (n1)-[:X]->(n2)
結果:
あなたはルート作成することにより、サイファーでそれを行うことができます。
CREATE (root:Root:Leaf);
は、あなたが必要な回数をレベルを追加するクエリを繰り返すことを(ただし、ある時点でトランザクションが大きくなりすぎる):
MATCH (n:Leaf)
REMOVE n:Leaf
FOREACH (i IN range(0, 7) |
CREATE (n)-[:CONTAINS]->(:Node:Leaf {value: coalesce(n.value, "") + toString(i)}));