cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Train explosion: Trying to iterate over a list to convert it into a linked list of nodes

mojo2go
Graph Buddy

I want to create a locomotive, and then add to it three train cars in succession where the first car is connected to the locomotive, the second car is connected to the first car, and the third car is connected to the second car. Below is my attempt, but it literally explodes.

CREATE (loco:Locomotive)
WITH ['car1', 'car2','car3'] AS carNames
UNWIND carNames AS carName
  MATCH (loco)-[:PULLS*0..2]->(last) WHERE NOT (last)-[:PULLS]->()
  MERGE (last)-[:PULLS]->(:Car {name:carName})
1 ACCEPTED SOLUTION

anthapu
Graph Fellow

This is where list being first class element in Cypher really helps.

Try this query

CREATE (loco:Locomotive)
WITH loco, ['car1', 'car2','car3'] as list
MERGE (loco)-[:PULLS]->(:Car {name:list[0]})
WITH list, list[1..] as nextList
UNWIND range(0,size(nextList)-1,1) as index 
WITH list[index] as first, nextList[index] as second 
MERGE (c1:Car {name:first})
MERGE (c2:Car {name:second})
MERGE (c1)-[:PULLS]->(c2)

View solution in original post

4 REPLIES 4

anthapu
Graph Fellow

This is where list being first class element in Cypher really helps.

Try this query

CREATE (loco:Locomotive)
WITH loco, ['car1', 'car2','car3'] as list
MERGE (loco)-[:PULLS]->(:Car {name:list[0]})
WITH list, list[1..] as nextList
UNWIND range(0,size(nextList)-1,1) as index 
WITH list[index] as first, nextList[index] as second 
MERGE (c1:Car {name:first})
MERGE (c2:Car {name:second})
MERGE (c1)-[:PULLS]->(c2)

You were so fast. I live in Norway. I wrote the question and went to sleep. By the time I looked I had two working solutions. This community is great, which is you guys.

ameyasoft
Graph Maven
Step 1: Create Cars nodes:

merge  (a1:Cars {name: 'car1'})
merge  (a2:Cars {name: 'car2'})
merge  (a3:Cars {name: 'car3'})

Step 2: Link the Cars

match (d:Cars)
with d order by id(d) ASC
with collect(d) as c2
CALL apoc.nodes.link(c2, 'PULLS')
return c2

Step 3: Link the engine to cars

match (d:Cars)
with d order by id(d) ASC
with collect(id(d)) as c2
unwind c2 as c3
with min(c3) as mn
match (f:Cars) where id(f) = mn
with f
merge (loco:Locomotive)
merge (loco)-[:CARS]->(f)
return loco, f

Result:

This is a great solution too. Easier for me to understand and test intermediate values. Thank you.