One of the areas in Neo4j and Cypher that brings the most questions and discussion when I’m giving Neo4j trainings or working with other engineers building with Neo4j, is around how to use Cypher
MERGE correctly and efficiently. The way I’ve explained Cypher MERGE to all our engineers and all the training attendees is this.
There are a few simple things to understand about how Neo4j handles Cypher MERGE operations to avoid undesired or unexpected behavior when using it.
1. The Cypher MERGE operation is a MATCH or CREATE of the entire pattern. This means that if any element of the pattern does NOT exist, Neo4j will attempt to create the entire pattern.
2. Always MERGE on each segment of the pattern that has the possibility to already exist.
3. After a MERGE operation you are guaranteed to have a useable reference to all identifiers established during the Cypher MERGE operation because they were either found or created.
2. Always MERGE on each segment of the pattern that has the possibility to already exist.
3. After a MERGE operation you are guaranteed to have a useable reference to all identifiers established during the Cypher MERGE operation because they were either found or created.
Simple Cypher MERGE Examples
Let’s look at a couple examples of Cypher MERGE operations:Assuming that a unique constraint exists on username for the User label and that (u:User {username: “neo”}) exists in the graph do you think these two statements are equivalent?
Statement 1:
MERGE (neo:User {username: “neo”})-[:KNOWS]->(trinity:User {username: “trinity”});
Statement 2:
MERGE (neo:User {username: “neo”})
MERGE (trinity:User {username: “trinity”})
MERGE (neo)-[:KNOWS]->(trinity);
MERGE (neo:User {username: “neo”})
MERGE (trinity:User {username: “trinity”})
MERGE (neo)-[:KNOWS]->(trinity);
The answer is no; they’re not equivalent. Here’s why they’re not:
In Statement 1 Neo4j will find that the entire pattern doesn’t MATCH because -[:KNOWS]->(trinity:User {username: “trinity”}) doesn’t exist in the graph.
This will cause Neo4j to attempt to create the entire pattern, which includes the already existing User node with a uniquely constrained
In Statement 1 Neo4j will find that the entire pattern doesn’t MATCH because -[:KNOWS]->(trinity:User {username: “trinity”}) doesn’t exist in the graph.
This will cause Neo4j to attempt to create the entire pattern, which includes the already existing User node with a uniquely constrained