Reputation: 511
I am using Neo4j (version 3.4.1) and Spring-data-neo4j (5.0.10.RELEASE) in my application. I am also using OGM.
I have the below relationship between my nodes:
A vehicle (V) has Part(s) (P1 and P2). Parts can be bought from dealers (D1, D2 and D3). Part themselves can be linked to each other (for e.g P2 is linked with P1)
I am trying to write a cypher query to get a Part node matching an id. I want to get the node along with its related nodes and relationships.
Below is my query:
@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);
When I run the query passing id of Part P1, I get the correct result. However, when I run it passing id of Part P2, I get an exception :
org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expected at most 1
which I understand is because in this case two parts are getting returned.
I would like to know the cypher query syntax so that I get correct result (i.e P2) along with its related nodes when I pass id of P2. I want that the P1 node should also be returned as P2 is linked with P1.
Any help would be highly appreciated.
Edit: Added queries to generate sample data.
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)
Regards, V
Upvotes: 2
Views: 1840
Reputation: 17
I see three problems here:
The first is that you're using a directed relationship in your 3rd MATCH
clause from part
to the unnamed node at the end:
MATCH q=(v)-[:HAS_PART]->(part)-[:FROM_DEALER|:IS_LINKED_WITH]->()
This means that when you query for P1, it does not match with P2, so the only : return P1
The second problem is that your query doesn't quite match your method, which is declared to return Optional<Part>
while your query wants to return all the nodes (and relationships) along that same path q
. Also the name of the method (findByIdForGivenPart
) is not quite expressing what you want to accomplish with it.
The third problem is that your first two MATCH clauses seem to have the alias name and specified labels switched in the syntax:
MATCH (Vehicle:v{id:{vehicleId}})
MATCH (Part:part{id:{id}})
I believe these should be:
MATCH (v:Vehicle {id:{vehicleId}})
MATCH (part:Part {id:{id}})
which also leads me to believe that you may have some test data in your graph with nodes that have labels such as v
and part
(instead of Vehicle
and Part
) possibly from earlier MERGE
statements that were intended to set up test data.
Upvotes: 1