具有文字结果的分层Cypher查询

时间:2014-07-27 12:50:47

标签: neo4j cypher

我的对象结构如下所示:有Container作为根节点,它有子容器。每个子容器都有任务,也有子任务。在Cypher MATCH中说明这一点:

  

(容器) - [:HAS_SUBCONTAINER] - GT;(subcont) - [:HAS_TASK] - GT;(任务) - [:HAS_TASK] - GT;(子任务)

我想编写一个返回此层次结构的JSON文字表示的查询:

{
  name: 'Main',
  subcontainers: [
    {
      name: 'Subcont',
      tasks: [
        {
          name: 'parent1',
          children: [
            {
              name: 'child1'
            }
          ]
        }
      ]
    }
  ]
}

有没有办法在Cypher中通过一个查询执行此操作?我找到了一个级别层次结构的解决方案:

MATCH (cnt:Container {name: 'Main'})-[:HAS_SUBCONTAINER]->(subcnt)
RETURN { name: cnt.name, subcontainers: EXTRACT(subc IN collect(subcnt)|{name: subc.name})}

但是,对于更复杂的案例,不能理解如何做到这一点。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

如果你知道匹配模式的深度,你可以在一系列收集中进行嵌套:

MATCH (container)-[:HAS_SUBCONTAINER]->(subcont)-[:HAS_TASK]->(task)-[:HAS_TASK]->(subtask)
WITH container, subcont, task, collect({name:subtask.name}) AS subtasks
WITH container, subcont, collect({name:task.name, children:subtasks}) AS tasks
WITH container, collect({name:subcont.name, tasks:tasks}) AS subconts
RETURN {
  name: container.name,
  subcontainers: subconts
} AS result

如果子任务是选项(@ jim-biard的问题),那么你需要一个可选的匹配和一个case语句:

MATCH (container)-[:HAS_SUBCONTAINER]->(subcont)-[:HAS_TASK]->(task)
OPTIONAL MATCH (task)-[:HAS_TASK]->(subtask)
WITH container, subcont, task, collect(
  CASE subtask
  WHEN NULL THEN NULL
  ELSE { name:subtask.name }
  END
) AS subtasks
WITH container, subcont, collect({name:task.name, children:subtasks}) AS tasks
WITH container, collect({name:subcont.name, tasks:tasks}) AS subconts
RETURN {
  name: container.name,
  subcontainers: subconts
} AS result