neo4j Cypher Иерархическое построение дерева ответ на JSON

Можете ли вы помочь мне построить запрос шифра? У меня есть следующая структура DB графа:

(parent:Category)-[:subcategory]->(child:Category)

С этими данными графика у меня есть иерархическое дерево с глубоким уровнем.

Я нашел следующий код на Stackoverfllow.com и изменил для моих данных:

MATCH (root:Category)-[:subcategory]->(parent:Category)-[:subcategory]->(child:Category)
WITH root, {category: parent, children: collect(child)} AS parent_with_children
WHERE NOT(()-[:subcategory]->(root))
RETURN {category: root, children: collect(parent_with_children)}

Но он строит ответ только на глубину с 3 уровнями дерева. Мне нужно больше. Я пытаюсь построить ответ JSON, как этот пример:

  [
    category: {
      name: "PC"
      children: {
        category: {
          name: "Parts"
          children: {
            category: {
              name: "CPU"
              ...
            }
          }
        },
        category: {
          name: "Accessories"
          ...
        }
      } 
    }, 
    category: {
      name: "Laptop"
      ...
    }
  ]

Сайфер может совершать рекурсивные звонки? Я думаю, что это будет лучше.

Благодарю.

Постскриптум Я знаю, что есть похожие вопросы по SO, но они мне не помогли.

 Brian Underwood26 июл. 2016 г., 09:38
Да, Сайфер на самом деле не делает рекурсию. При возврате дерева данных ваша лучшая ставка заключается в том, что предложено киберсамом ниже, или возвращает узлы / отношения в виде таблицы и строит их в памяти.

Ответы на вопрос(1)

Решение Вопроса

Cypher не очень подходит для сброса данных графа в древовидную структуру, когда листья находятся на произвольной глубине.

Тем не менее, с neo4j 3.x, вы можете приблизиться к тому, что вы хотите, если вы можете установитьПлагин APOC на вашем сервере и использоватьapoc.convert.toTree процедура.

Сначала давайте создадим несколько примеров данных:

CREATE
  (c1:Category {name: 'PC'}),
    (c1)-[:subcategory]->(c2:Category {name: 'Parts'}),
      (c2)-[:subcategory]->(c3:Category {name: 'CPU'}),
        (c3)-[:subcategory]->(c4:Category {name: 'CacheRAM'}),
    (c1)-[:subcategory]->(c5:Category {name: 'Accessories'}),
      (c5)-[:subcategory]->(c6:Category {name: 'Mouse'}),
      (c5)-[:subcategory]->(c7:Category {name: 'Keyboard'}),
  (c10:Category {name: 'Laptop'}),
    (c10)-[:subcategory]->(c20:Category {name: 'Parts'}),
      (c20)-[:subcategory]->(c30:Category {name: 'CPU'}),
    (c10)-[:subcategory]->(c40:Category {name: 'Accessories'}),
      (c40)-[:subcategory]->(c50:Category {name: 'Stylus'});

Тогда с этим запросом:

MATCH p=(n:Category)-[:subcategory*]->(m)
WHERE NOT ()-[:subcategory]->(n)
WITH COLLECT(p) AS ps
CALL apoc.convert.toTree(ps) yield value
RETURN value;

... вы получите N строк результата, где N - номер корняCategory узлы. Вот фрагмент примера результатов:

{
  ...
      "row": [
        {
          "_id": 150,
          "_type": "Category",
          "name": "PC",
          "subcategory": [
            {
              "_id": 154,
              "_type": "Category",
              "name": "Accessories",
              "subcategory": [
                {
                  "_id": 156,
                  "_type": "Category",
                  "name": "Keyboard"
                },
                {
                  "_id": 155,
                  "_type": "Category",
                  "name": "Mouse"
                }
              ]
            },
            {
              "_id": 151,
              "_type": "Category",
              "name": "Parts",
              "subcategory": [
                {
                  "_id": 152,
                  "_type": "Category",
                  "name": "CPU",
                  "subcategory": [
                    {
                      "_id": 153,
                      "_type": "Category",
                      "name": "CacheRAM"
                    }
                  ]
                }
              ]
            }
          ]
        }
      ],
  ...
      "row": [
        {
          "_id": 157,
          "_type": "Category",
          "name": "Laptop",
          "subcategory": [
            {
              "_id": 158,
              "_type": "Category",
              "name": "Parts",
              "subcategory": [
                {
                  "_id": 159,
                  "_type": "Category",
                  "name": "CPU"
                }
              ]
            },
            {
              "_id": 160,
              "_type": "Category",
              "name": "Accessories",
              "subcategory": [
                {
                  "_id": 161,
                  "_type": "Category",
                  "name": "Stylus"
                }
              ]
            }
          ]
        }
      ],
  ...
}

Ваш ответ на вопрос