How to create relationship using FOREACH

I have Person and Course nodes. How I can create the relationships from one Person to many Courses using FOREACH? I tried the following as the example but it returns two new empty nodes, two new nodes with Courses and one new relationship between each pair of nodes.

Match (r: Course ), (p:Person {role:'Student', firstname:'John',lastname:’Smith'})

with ["Chemistry", "Physics"] as rid_array

foreach (i in range(0,size(rid_array)-1)|

merge out = (p)-[req:HAS_COURSE]->(r {course_name: rid_array[i]}))

return out

Can't create node `r` with labels or properties here. The variable is already declared in this context

The variables 'r' and 'p' are not being passed on. Add these varibles in line 2 and try.
with ["Chemistry", "Physics"] as rid_array, r, p
Try this:

merge (p:Person {role:'Student', firstname:'John', lastname:'Smith'})

with ["Chemistry", "Physics"] as rid_array, p
 foreach (i in range(0,size(rid_array)-1)|
 merge (r:Course {course_name: rid_array[i]})
 merge (p)-[req:HAS_COURSE]->(r)
 )

@ameyasoft is absolutely correct, but it can be simplified, as you can iterate over the array directly.

with ["Chemistry", "Physics"] as rid_array
merge (p:Person {role:'Student', firstname:'John', lastname:'Smith'})
foreach (i in rid_array |
    merge (r:Course {course_name: i})
    merge (p)-[req:HAS_COURSE]->(r)
)
If you want to use FOREACH, try this: A slight modification of @gillienfield code.

with ["Chemistry", "Physics"] as rid_array
match (p:Person {role:'Student', firstname:'John', lastname:'Smith'})
foreach (i in rid_array |
    merge (r:Course {course_name: i})
    merge (p)-[req:HAS_COURSE]->(r)
)

two new nodes have been created and the relationships have been added to them. I need to create just relationship from one existing node Person (John Smith) to two existing courses.

That is odd, as the merge will look for an existing node before it creates a new one. Also, the merge on the relationship is referencing node variables so, it shouldn't create new ones as well. We can change the merge to a match, but match is not allowed in a foreach loop, so we will need to refactor the code.

with ["Chemistry", "Physics"] as rid_array
merge (p:Person {role:'Student', firstname:'John', lastname:'Smith'})
with rid_array, p
unwind rid_array as rid
match (r:Course {course_name: rid})
merge (p)-[req:HAS_COURSE]->(r)

Screen Shot 2023-02-06 at 10.13.49 AM.png

Screen Shot 2023-02-06 at 10.14.35 AM.png

BTW- you can have multiple labels on a node. It may be a better approach to add a label for your 'role' instead of a property.

@glilienfield Thanks but this query creates two new nodes 'Chemistry' and 'Physics' and then creates two relationships from Person to these new nodes. I need to create just relationships from node Person ('John Smith') to existing two nodes 'Chemistry' and 'Physics' in the loop,

I am confused with the migration back to the old platform. Did we resolve your issue?