2016-11-25 2 views
0

Я хотел бы создать octree структуры в Neo4j с помощью Cypher. Я хотел бы создать что-то похожее на рисунке ниже:Создание простой octree структуры в Neo4j с использованием Cypher

octree

Любые идеи о том, как это может быть реализовано без необходимости создания каждого узла и отношения «вручную»?

ответ

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 и выполнить эти заявления.
Если вы не уверены, как это сделать, можно просто распечатать Cypher заявления, а затем вставить их в нео оболочку или браузер
здесь есть выход работает create_tree(0,2) Выходных данных показывает, родитель с последующим его восьмью детьми

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, 

дайте мне знать, если это то, что вы искали

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) 

Это приводит к следующему дереву:

enter image description here

Объяснение: для дерева уровней к, мы копируем branches переменные к-1 раз, и раскручивать каждый список. Это создает декартово произведение, следовательно, производя узлы листа. Для (полных) бинарных деревьев k уровней это приводит к 2^(k-1) листовым узлам. (Это также работает для осей, которые будут иметь уровни 8^(k-1).)

Мы объединяем номера уровней с символами подчеркивания для создания уникальных имен переменных для каждого уровня. Идентификаторы могут быть запрошены как таковой:

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) 

Результат:

enter image description here

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)}));