Neo4j Cypher - 转换为树时在路径中链接可选关系

问题描述 投票:0回答:1

我在 Neo4j 中保存了一些节点,并希望将它们作为树返回。我的模型看起来像这样:

RootNode -HAS_CHILDREN-> Element
Element -HAS_CHILDREN-> Element
Element -HAS_ANOTHER_RELATIONSHIP-> AnotherNode

我运行的查询:

    const rootNodeAlias = 'r';
    const elementAlias = 'e';
    const anotherNodeAlias = 'a';
    const query "= 
        MATCH (${rootNodeAlias}:RootNode {id: $id})
  
        // Match the related elements
        OPTIONAL MATCH (${rootNodeAlias})-[:HAS_CHILDREN]->(${elementAlias}:Element)

        // Fetch the element tree
        CALL {
            WITH ${elementAlias}
            OPTIONAL MATCH path=(${elementAlias})-[rel:HAS_CHILDREN*0..]->(child:Element)-[:HAS_ANOTHER_RELATIONSHIP]->(${anotherNodeAlias}:AnotherNode)
            WITH COLLECT(path) AS paths
            CALL apoc.convert.toTree(paths) YIELD value AS tree
            RETURN tree AS elementTree
        }
        
        // Return the root node and its related elements with their children
        RETURN ${rootNodeAlias} AS root,
               collect(elementTree) AS elementTrees
      ;"

问题是,如果一个元素没有

HAS_ANOTHER_RELATIONSHIP
AnotherNode
,那么这里的路径:

OPTIONAL MATCH path=(${elementAlias})-[rel:HAS_CHILDREN*0..]->(child:Element)-[:HAS_ANOTHER_RELATIONSHIP]->(${anotherNodeAlias}:AnotherNode)

也不会返回

HAS_CHILDREN
关系。我尝试了这样的可选匹配:

OPTIONAL MATCH path=(${elementAlias})-[rel:HAS_CHILDREN*0..]->(child:Element) OPTIONAL MATCH (child)-[:HAS_ANOTHER_RELATIONSHIP]->(${anotherNodeAlias}:AnotherNode)

但是没有成功。它仅返回

HAS_CHILDREN
关系。

是否有任何方法可以在路径中添加这两种关系(如果其中之一存在)? 如果无法在路径内完成此操作,解决方法是什么?

提前谢谢您!

neo4j cypher
1个回答
0
投票

如果您使用的是 Neo4j > 5.9,您可以使用 量化路径模式 来编写:

MATCH (r:RootNode)
OPTIONAL MATCH path = (r)-[:HAS_CHILDREN]->+(:Element) 
                      (()-[:HAS_ANOTHER_RELATIONSHIP]->(:AnotherNode)){0,1}
WITH r, COLLECT(path) AS paths
CALL apoc.convert.toTree(paths) YIELD value AS tree
RETURN r AS root, collect(tree) AS elementTrees

{0,1}
量词将包含最后的
HAS_ANOTHER_RELATIONSHIP
(如果存在),而无需使用第二个
OPTIONAL

以下内容适用于版本 < 5.9, as long as there are no nodes with both labels

Element
AnotherNode

MATCH (r:RootNode)
OPTIONAL MATCH path = (r)-[:HAS_CHILDREN*]->(:Element)-[:HAS_ANOTHER_RELATIONSHIP*0..1]->
                      (:Element|AnotherNode)
WITH r, COLLECT(path) AS paths
CALL apoc.convert.toTree(paths) YIELD value AS tree
RETURN r AS root, collect(tree) AS elementTrees
© www.soinside.com 2019 - 2024. All rights reserved.