Benjamin McFerren
Benjamin McFerren

Reputation: 862

Cypher: How to use FOREACH on an array of objects to create multiple nodes and multiple relationships

I am having trouble with the fetch described in the title of this question. My attempt is the following string:

FOREACH (_tabobj IN {_tabarray} |
  MATCH (a:Superlabel),(b)
  WHERE a.id = {_parentid} AND b.id = _tabobj.id
  MERGE (a)-[r:INCLUDES]->(b {
      name    : _tabobj.name
  })

I am trying to only create the relationship if it is not already in the database and nothing if the relationship is already in the database. Also trying to only create the b node if it is not already in the database and nothing if the b node is already in the database.

I am very grateful for help you can offer

Upvotes: 3

Views: 2185

Answers (1)

Brian Underwood
Brian Underwood

Reputation: 10856

How about something like this:

MATCH (a:Superlabel {id: {_parentid}})
WITH a, tabarray IN {_tabarray}
UNWIND tabarray AS tabobj
MATCH (b {id: tabobj.id)
MERGE (a)-[r:INCLUDES]->(b {name: tabobj.name})

I generally use FOREACH as a last resort ;)

And a simpler solution:

MATCH (a:Superlabel {id: {_parentid}}), (b)
WHERE b.id IN EXTRACT(tabobj IN {_tabarray} | tabobj.id)
MERGE (a)-[r:INCLUDES]->(b {name: tabobj.name})    

An important consideration for both of these queries: When matching the b node on the id property the database index (if you have one) won't be used because indexes are for a label / property pair. Specifying a label for b, if applicable, could help performance.

Upvotes: 1

Related Questions