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.

HELP with Cypher Query: MERGE if not exists

mrksph
Node Clone

Hi there,

I'm reworking one of our cypher scripts. The cypher snippet when executed should create the following graph structure:

The parent node data is made from info from a :Client node, then the :Client node's code and the name are also set in the (purple) child node.

A Client can be PARENT_OF other Clients in our database, depending on the input data we load the database from.

MATCH (g:Client:Group)-[:PARENT_OF]->(:Client {isVirtualG:TRUE})
WITH
COLLECT(DISTINCT(g)) AS groups
UNWIND groups AS group
MATCH (ctr:Counter {code: 'JQCLCFNI'})
SET ctr.count = ctr.count + 1

CREATE (ch:CustomHierarchy:Fixed {codeV: 'JQCLCFNI' + substring('000000', size(toString(ctr.count))) + toString(ctr.count) + 'V001', name: 'Fixed Pre-Classification Hierarchy for Group'})

CREATE (ccg:Custom:Group:Real {code: group.code, name: group.name})

CREATE (ch)-[:INCLUDES {id: apoc.create.uuid()}]->(ccg);

What I want to do is when RELOADING the database with new data, instead of ALWAYS creating from scratch all this structure, I would like to first look if there's an existing children node with a given Client code. If it doesn't exist, then create the :CustomHierarchy structure, if it does exists, do nothing.

I know about MERGE, I just don't know how to chain it in my query. I've thought about the query starting with something like this:

MATCH (group:Custom:Group:Real)
WHERE group.code = $code
OPTIONAL MATCH (group)<-[]-(existingCustom:CustomHierarchy)
WITH existingCustom
MERGE (newCustom:CustomHierarchy {codeV:existingCustom.codeV})
ON CREATE
SET 
. . .
. . .

EDIT: What about this? First I match a child node because it's the only way to check if the structure already exists. Then I OPTIONALO MATCH and retrieve the 'existingCustom' and pass it down using WITH. Then I can MERGE.

While writing this I'm realizing that if it doesn't exists it will create the CustomHierarchy node but the codeV property wouldn't match the existing pattern we created for it.... But I think I'm getting closer

Any help appreciated

1 REPLY 1

I didn't fully dive into it, here is my suggestion:

MATCH (g:Client:Group)-[:PARENT_OF]->(:Client {isVirtualG:TRUE})
WITH
COLLECT(DISTINCT(g)) AS groups
UNWIND groups AS group
MATCH (ctr:Counter {code: 'JQCLCFNI'})
SET ctr.count = ctr.count + 1

// assuming this is the id
// but your ctr increase will alwasy cause this to create new nodes!!
MERGE (ch:CustomHierarchy:Fixed {codeV: 'JQCLCFNI' + substring('000000', size(toString(ctr.count))) + toString(ctr.count) + 'V001'}) ON CREATE SET ch.name='Fixed Pre-Classification Hierarchy for Group'

// assuming this is the id
MERGE (ccg:Custom:Group:Real {code: group.code, name: group.name})

MERGE (ch)-[rel:INCLUDES]->(ccg) ON CREATE SET rel.id=apoc.create.uuid();