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.

Unable to create relation with FOREACH clause

oli
Graph Buddy

Hi, I'm trying to create relation to link event

MATCH (c:Car {carID:car_ID})-[:takePlace]->(e:Event)
with e ORDER BY e.start_time
with collect(e) as events
FOREACH(i in RANGE(0, size(events)-2) |
     create (events[i])-[:NEXT]->(events[i+1]))

And I got the fullowing error


Anyone knows why would this happen?

Thanks,
Oli

1 ACCEPTED SOLUTION

According to the documentation: within the FOREACH parentheses, you can do any of the updating commands — SET , REMOVE , CREATE , MERGE , DELETE , and FOREACH. So in your case, I don't see how you can use it since you need to match both nodes.

The best solution is this one:

MATCH (c:Car {carID: car_ID})-[:takePlace]->(e:Event)
WITH e
ORDER BY e.start_time
WITH collect(e) AS events
UNWIND RANGE(0, size(events)-2) AS i
MATCH (a:Event {eventID: events[i].eventID})
MATCH (b:Event {eventID: events[i+1].eventID})
CREATE (a)-[:NEXT]->(b)

View solution in original post

7 REPLIES 7

Hello @oli

You cannot use a list item to match a node, you must do like this:

MATCH (c:Car {carID: car_ID})-[:takePlace]->(e:Event)
WITH e
ORDER BY e.start_time
WITH collect(e) AS events
UNWIND RANGE(0, size(events)-2) AS i
MATCH (a:Event) WHERE a.your_property = events[i].your_property 
MATCH (b:Event) WHERE b.your_property = events[i+1].your_property
CREATE (a)-[:NEXT]->(b)

Regards,
Cobra

Hello Cobra,
Thanks for your reply, my purpose is that I wish to link all my nodes inside the list without searching outside. If I'm not understanding wrong, neo4j doesn't support event[i] to represent a node even if it does a node?(I tried like "with event[i] as e1", and it works, but the with clause cannot be inside FOREACH clause)

Yes, that's why you must use a MATCH clause, do you have a unique property for your Event nodes?

Yes, I do. I have a generated eventID(combined with several properties), May I ask that what if I would to use FOREACH, how could I deal with the event[i]?

According to the documentation: within the FOREACH parentheses, you can do any of the updating commands — SET , REMOVE , CREATE , MERGE , DELETE , and FOREACH. So in your case, I don't see how you can use it since you need to match both nodes.

The best solution is this one:

MATCH (c:Car {carID: car_ID})-[:takePlace]->(e:Event)
WITH e
ORDER BY e.start_time
WITH collect(e) AS events
UNWIND RANGE(0, size(events)-2) AS i
MATCH (a:Event {eventID: events[i].eventID})
MATCH (b:Event {eventID: events[i+1].eventID})
CREATE (a)-[:NEXT]->(b)

Thanks Cobra,
I'm just wandering that what if I don't match the event but just iterate the node and link it?

MATCH (c:Car {carID: car_ID})-[:takePlace]->(e:Event)
WITH e
ORDER BY e.start_time
WITH collect(e) AS events
UNWIND RANGE(0, size(events)-2) AS i
WITH events[i] AS a,  events[i+1] AS b
CREATE (a)-[:NEXT]->(b)

If I wrote the code in this way, it will be no problem (use WITH...AS... instead events[i] directly)
I don't know if this will be more efficient since there is no extra matching cost?
Hope to discuess with you

Yes, your solution with the WITH clause should be more efficient, I did not have to wake up fully . You can compare both queries with the PROFILE keyword.