我在我的应用程序中使用Neo4j(3.4.1版)和Spring-data-neo4j(5.0.10.RELEASE)。我也在使用OGM。
我的节点之间具有以下关系:
车辆(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)及其相关节点。 我希望当P2与P1链接时也应返回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
答案 0 :(得分:1)
我在这里看到三个问题:
第一个是您正在从MATCH
到末尾的未命名节点的第三个part
子句中使用 directed 关系:
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}})
这也使我相信,您的图形中可能包含带有v
和part
(而不是Vehicle
和{{1})等标签的节点的一些测试数据。 })可能来自旨在建立测试数据的早期Part
语句。