0

Cypher を使用して Neo4j で octree 構造を作成したいと考えています。以下の図のようなものを作成したいと思います。

オクトリー

各ノードと関係を「手動で」作成することなく、これをどのように実装できるかについてのアイデアはありますか?

4

3 に答える 3

1

ルートを作成することにより、Cypherでそれを行うことができます:

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)}));
于 2016-11-25T22:32:27.907 に答える
1

ツリーの高さが事前にわかっている場合は、Cypher を使用してツリーを生成できます。簡単にするために、(分岐係数が 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変数を k-1 回コピーし、各リストを巻き戻します。これによりデカルト積が作成されるため、リーフ ノードが作成されます。k レベルの (完全な) バイナリ ツリーの場合、これは 2^(k-1) リーフ ノードになります。(これは、8^(k-1) レベルを持つ octree でも機能します。)

レベルの番号をアンダースコアと組み合わせて、各レベルに一意の変数名を作成します。ID は次のように照会できます。

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      │
└────┴───┴─────────┘

あとはノードとリレーションシップを作成するだけですが、ノード/エッジは 1 回しか作成されないことに注意してください。これは、 を使用することで保証されMERGEます。(MERGE最初は難しいように思えるかもしれませんが、適切な説明があります。)

さらにレベルを追加する場合は、次のようにクエリを更新します。

  • ブランチから新しい変数を定義します。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)

結果:

ここに画像の説明を入力

于 2016-11-25T22:02:17.960 に答える
0

cypher だけでできるかどうかはわかりませんが、プログラミング言語を使用して neo4j に接続し、ノードと関係を作成できます。
たとえば、PHP では次のようになります。

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 ステートメントがある場所では、neo4j インスタンスに接続してそれらのステートメントを実行する必要があります。
その方法がわからない場合は、サイファーステートメントを印刷して、neo シェルまたはブラウザに貼り付けることができます。
ここに実行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,

それがあなたが探していたものかどうか教えてください

于 2016-11-25T19:12:20.807 に答える