我的对象结构如下所示:有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})}
但是,对于更复杂的案例,不能理解如何做到这一点。有什么想法吗?
答案 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