Mike Furlender
Mike Furlender

Reputation: 4019

How to prevent neo4j MERGE from creating duplicate relationships?

I am attempting to create nodes and relationships if they do not exist. I do not know ahead of time if anything in the DB exists.

This is my initial query:

MERGE (t:type { name: 'aaa'})
MERGE (m:model { name: 'bbb'})
MERGE (r:region {name: 'ccc'})
MERGE (p:param {name: 'ddd'})
MERGE (i:init {value: 123})
MERGE (u:forecast {url: 'http://something.png'})
MERGE (t)-[:HAS]-(m)-[:HAS]-(r)-[:HAS]-(p)-[:HAS]-(i)-[:HAS]-(u)

This correctly produces a graph like this: first graph output

Then I run this query again, but this time I change the name of the "model" object to "bbc" (instead of "bbb"):

MERGE (t:type { name: 'aaa'})
MERGE (m:model { name: 'bbc'})
MERGE (r:region {name: 'ccc'})
MERGE (p:param {name: 'ddd'})
MERGE (i:init {value: 123})
MERGE (u:forecast {url: 'http://something.png'})
MERGE (t)-[:HAS]-(m)-[:HAS]-(r)-[:HAS]-(p)-[:HAS]-(i)-[:HAS]-(u)

Now, however, my graph looks like this: second graph

Everything looks correct except for the three duplicated relationships. I realize that MATCH will create the whole path if it does not exist. There must be some way to avoid creating duplicate relationships, though.

I would appreciate being pointed in the right direction!

Upvotes: 1

Views: 647

Answers (1)

Brakebein
Brakebein

Reputation: 2237

The MERGE statement checks if the pattern as a whole already exists or not. So, if there is one node different, the whole pattern is determined as non-existent and all relationships are created.

The solution is to split this MERGE statement into multiple, i.e. one MERGE for each relationship:

MERGE (t)-[:HAS]-(m)-[:HAS]-(r)-[:HAS]-(p)-[:HAS]-(i)-[:HAS]-(u)

becomes

MERGE (t)-[:HAS]-(m)
MERGE (m)-[:HAS]-(r)
MERGE (r)-[:HAS]-(p)
MERGE (p)-[:HAS]-(i)
MERGE (i)-[:HAS]-(u)

Upvotes: 2

Related Questions