Neo4j & Cypher: Creating Relationships Between a Collection of Nodes / Invalid input ‘[‘:
Join the DZone community and get the full member experience.
Join For FreeWhen working with graphs we’ll frequently find ourselves wanting to create relationships between collections of nodes.
A common example of this would be creating a linked list of days so that we can quickly traverse across a time tree. Let’s say we start with just 3 days:
MERGE (day1:Day {day:1 }) MERGE (day2:Day {day:2 }) MERGE (day3:Day {day:3 }) RETURN day1, day2, day3
And we want to create a ‘NEXT’ relationship between adjacent days:
(day1)-[:NEXT]->(day2)-[:NEXT]->(day3)
The most obvious way to do this would be to collect the days into an ordered collection and iterate over them using FOREACH, creating a relationship between adjacent nodes:
MATCH (day:Day) WITH day ORDER BY day.day WITH COLLECT(day) AS days FOREACH(i in RANGE(0, length(days)-2) | CREATE UNIQUE (days[i])-[:NEXT]->(days[i+1]))
Unfortunately this isn’t valid syntax:
Invalid input '[': expected an identifier character, node labels, a property map, whitespace, ')' or a relationship pattern (line 6, column 32) " CREATE UNIQUE (days[i])-[:NEXT]->(days[i+1]))" ^
It doesn’t seem to like us using array indices where we specify the node identifier.
However, we can work around that by putting days[i] and days[i+1] into single item arrays and using nested FOREACH loops on those, something Michael Hunger showed me last year and I forgot all about!
MATCH (day:Day) WITH day ORDER BY day.day WITH COLLECT(day) AS days FOREACH(i in RANGE(0, length(days)-2) | FOREACH(day1 in [days[i]] | FOREACH(day2 in [days[i+1]] | CREATE UNIQUE (day1)-[:NEXT]->(day2))))
Now if we do a query to get back all the days we’ll see they’re connected:

Published at DZone with permission of Mark Needham, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments