Match nodes in a FOREACH statement

I understand neo4j doesnt allow MATCH in FOREACH statements but I dont quite know how to merge my nodes to existing nodes without using the match statetement. (My code explains it better)

UNWIND $data as row
MERGE (a:Assembly)
UNWIND $components as components
FOREACH(id IN components.uuid | MATCH (c:Component {_uuid: id})
MERGE (a)-[:RECIPE]->(c))

However if I just use merge then I will be creating new component nodes and not match them to the components that i already have. I am looking for a query that can help me solve this task

Disclaimer: I see a simalar question in the community but i dont quite understand the answer given as such I put my own problem.

UNWIND $data as row
MERGE (a:Assembly)
UNWIND $components as component
MATCH (c:Component {_uuid: component.uuid}
MERGE (a)-[:RECIPE]->(c)

Thank you for the quick reply. This answer worked for me. Please correct we if im wrong. From what I understand, I can use the UNWIND similarly to the FOREACH as long whats in the 'UNWIND' has the same format (not sure if this is the correct term)

There's three main types grouping/storing data in Cypher:

  • Map -- Like an object: prop: {key: val, key: val2, ...}
  • List -- Like an array: prop: [val1, val2, ...]
  • Simple -- Simple: prop: val

FOREACH, and UNWIND, operate on Lists, but do it in different ways. While they may appear similar, FOREACH is very limited in what commands in can run within the loop, but can do it much faster than UNWIND.

UNWIND brings each element in the list into the main body of the Cypher statement.

FOREACH runs one simple command on each element in the list.

Thanks this helped a lot

I should add two very useful things about lists:

list compression:

Any list, including those returned by functions, can be filtered, and operated on, with a relatively simple syntax.


RETURN [x in [0,1,2,3,4,5] WHERE (x % 2) - 1 = 0 | x / 2] AS result
// [0.5, 1.5, 2.5]


CREATE (temp:Thing {prop1: 1; prop2: 2; prop3: 3})
RETURN [k IN KEYS(temp) WHERE temp[k] % 2 != 0 | k + "--" + temp[k]] AS result
// [ "prop1--1", "prop3--3" ]


When you need to compress a list into a single value, like an average, this is your tool. Note that Cypher aggregating functions like AVG() operate on variable in the main body, rather than lists.

WITH [1, 2, 3, 4, 5] AS list1
RETURN REDUCE(sum = 0, val IN list1 | sum + val) / SIZE(list1) AS average