Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
02-03-2023 06:39 AM
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
02-03-2023 08:30 AM
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
02-03-2023 01:39 PM
Can't create node `r` with labels or properties here. The variable is already declared in this context
02-03-2023 04:00 PM
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)
)
02-03-2023 06:05 PM
@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)
)
02-06-2023 06:13 AM
@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,
02-06-2023 06:24 AM
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.
02-06-2023 07:15 AM - edited 02-06-2023 07:26 AM
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)
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.
02-06-2023 07:40 AM
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)
)
All the sessions of the conference are now available online