0
votes

I am using Neo4j (version 3.5.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:

enter image description here A vehicle (V) has Part(s) (P1, P2 and P3). Parts can themselves be linked with other parts (for e.g P2 is linked with P6)

I am trying to write a cypher query to get all the parts in a vehicle. However, I want to paginate the results and also want to order the parts ordered by the creation date (part created recently is returned first)

Below is my query:

MATCH (vehicle: Vehicle{id:{vehicleId}})
WITH vehicle MATCH p=(vehicle)-[:HAS_PART]-(part:Part)
WITH p, part SKIP 1 LIMIT 1 OPTIONAL MATCH m=(part)-[:IS_LINKED_WITH]->(:Part)
RETURN collect(nodes(p)), collect(relationships(p)), collect(nodes(m)), collect(relationships(m))

I sometimes get result size greater than 1. Also I am not sure how to order the returned Part by creation date (Part node has creationDate property set when it is created).

Any help would be highly appreciated. Thanks.

Data can be create as follows:

merge (v:Vehicle{id:'V1'})-[:HAS_PART]->(p:Part{id:'P1'})-[:IS_LINKED_WITH]->(p:Part{id:'P5'})

match (v :Vehicle{id:'V1'})
merge (v)-[:HAS_PART]->(p:Part{id:'P3'})

match (v :Vehicle{id:'V1'})
merge (v)-[:HAS_PART]->(p:Part{id:'P2'})-[:IS_LINKED_WITH]->(p:Part{id:'P6'})
1

1 Answers

0
votes

You don't need to define paths in your patterns for this.

First match all parts of the vehicle (use :HAS_PART*.. if you have chained HAS_PART relationships):

MATCH (v:Vehicle {id:'V1'})-[:HAS_PART]-(part:Part)

I suppose not all parts have a IS_LINKED_WITH relationship, so use OPTIONAL MATCH for the linked parts (if you used only MATCH you wouldn't get parts with 0 linked relationships)

OPTIONAL MATCH (part)-[:IS_LINKED_WITH]-(linked:Part)

then collect all of the parts and use UNWIND so they are in single variable

WITH COLLECT(DISTINCT part) + COLLECT(DISTINCT linked) as allParts
UNWIND allParts as part

And use regular RETURN, ORDER BY, SKIP and LIMIT clauses:

RETURN DISTINCT part.id 
ORDER BY part.id
SKIP 1 LIMIT 2

The whole query:

MATCH (v:Vehicle {id:'V1'})-[:HAS_PART]-(part:Part)
OPTIONAL MATCH (part)-[:IS_LINKED_WITH]-(linked:Part)
WITH COLLECT(DISTINCT part) + COLLECT(DISTINCT linked) as allParts
UNWIND allParts as part
RETURN DISTINCT part.id 
ORDER BY part.id
SKIP 1 LIMIT 2