Neo4j - 获取给定节点的所有相关节点和关系

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

我在我的应用程序中使用Neo4j(版本3.4.1)和Spring-data-neo4j(5.0.10.RELEASE)。我也在使用OGM。

我的节点之间有以下关系:

enter image description here

车辆(V)具有部件(P1和P2)。零件可以从经销商处购买(D1,D2和D3)。部分本身可以相互链接(例如,P2与P1链接)

我正在尝试编写一个密码查询来获取与id匹配的Part节点。我想获得节点及其相关的节点和关系。

以下是我的查询:

@Query(("MATCH (Vehicle:v{id:{vehicleId}}) \n" +
            "MATCH (Part:part{id:{id}}) \n" +
            "WITH DISTINCT part \n" +
            "MATCH q=(v)-[:HAS_PART]->(part)-[:FROM_DEALER|:IS_LINKED_WITH]->()\n" +
            "RETURN nodes(q), relationships(q)"))
    Optional<Part> findByIdForGivenPart(@Param("vehicleId") String vehicleId, @Param("id") String id);

当我运行查询传递部分P1的id时,我得到了正确的结果。但是,当我运行它传递部分P2的id时,我得到一个例外:

org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expected at most 1   

我理解的是因为在这种情况下有两个部分被归还。

我想知道密码查询语法,以便在我传递P2的id时得到正确的结果(即P2)及其相关节点。我希望P1节点也应该返回,因为P2与P1链接。

任何帮助将受到高度赞赏。

编辑:添加查询以生成样本数据。

merge (v:Vehicle{id:'V1'})-[:HAS_PART]->(p:Part{id:'P1'})-[:FROM_DEALER]->(d1:Dealer{id:'D1'})

match(p:Part{id:'P1'})
merge (p)-[:FROM_DEALER]->(d2:Dealer{id:'D2'})

match (v :Vehicle{id:'V1'})
match (d2:Dealer{id:'D2'})
merge (v)-[:HAS_PART]->(p:Part{id:'P2'})-[:FROM_DEALER]->(d2)

match(p2:Part{id:'P2'})
match(p1:Part{id:'P1'})
merge (p2)-[:FROM_DEALER]->(d3:Dealer{id:'D3'})
merge (p2)-[:IS_LINKED_WITH]->(p1)

问候,V

neo4j cypher spring-data-neo4j neo4j-ogm
1个回答
1
投票

我在这里看到三个问题:

首先,你在MATCH的第3个part条款中使用了一个有向关系,最后是未命名的节点:

MATCH q=(v)-[:HAS_PART]->(part)-[:FROM_DEALER|:IS_LINKED_WITH]->()

这意味着当您查询P1时,它与P2不匹配,因此唯一:返回P1

第二个问题是您的查询与您的方法不完全匹配,当您的查询想要返回沿着相同路径Optional<Part>的所有节点(和关系)时,该方法被声明为返回q。此方法的名称(findByIdForGivenPart)并不能完全表达您想要用它完成的任务。

第三个问题是你的前两个MATCH子句似乎在语法中切换了别名和指定的标签:

MATCH (Vehicle:v{id:{vehicleId}})
MATCH (Part:part{id:{id}})

我相信这些应该是:

MATCH (v:Vehicle {id:{vehicleId}})
MATCH (part:Part {id:{id}})

这也让我相信你可能在图表中有一些测试数据,其中包含vpart(而不是VehiclePart)等标签的节点可能来自用于设置测试数据的早期MERGE语句。

© www.soinside.com 2019 - 2024. All rights reserved.