merge
The merge
module provides the capabilities of the MERGE
Cypher command, merging or creating nodes and relationships as per specified conditions.
It ensures precision and coherence in managing interconnected data structures.
Trait | Value |
---|---|
Module type | util |
Implementation | C++ |
Graph direction | directed/undirected |
Edge weights | weighted/unweighted |
Parallelism | sequential |
Procedures
You can execute this algorithm on graph projections, subgraphs or portions of the graph.
node()
The procedure provides a more flexible way of merging nodes than Cypher’s MERGE
clause, by
allowing labels and properties to be extracted as results of other procedures
and sent as a list or map.
Input:
-
subgraph: Graph
(OPTIONAL) ➡ A specific subgraph, which is an object of type Graph returned by theproject()
function, on which the algorithm is run. If subgraph is not specified, the algorithm is computed on the entire graph by default. -
labels: List[string]
➡ A list of all labels that need to be added to the new node. -
identProps: Map
➡ A map with key-value pairs used for identifying which nodes will be merged. -
createProps: Map
➡ A map with key-value pairs which represent properties of the node, when the procedure creates a new node. Equivalent to usingON CREATE SET
for properties when usingMERGE
. -
mergeProps: Map
➡ A map with key-value pairs which represent properties of the node, when the procedure merges onto a node. Equivalent to usingON MATCH SET
for properties when usingMERGE
.
Output:
node: Node
➡ The node which was created or merged in the procedure.
Usage:
Consider a graph with two Human
, and one Alien
node.
CREATE (h:Human {name:"Mark", age: 20}), (h2:Human {name:"Eva", age: 30}), (a:Alien {name: "Gorlock", age: 20});
Use the merge.node()
procedure on all nodes, and add galaxy
property on the existing nodes. By leaving labels
and identProp
empty,
all nodes in the graph will be affected by the procedure.
CALL merge.node([],{},{},{galaxy: "Milky way"})
YIELD node
RETURN node;
+----------------------------------------------------------------------------------------------------------------+
| node |
+----------------------------------------------------------------------------------------------------------------+
| {"id": 0,"labels": ["Human"],"properties": {"age": 20,"galaxy": "Milky way","name": "Mark"},"type": "node"} |
+----------------------------------------------------------------------------------------------------------------+
| {"id": 1,"labels": ["Human"],"properties": {"age": 30,"galaxy": "Milky way","name": "Eva"},"type": "node"} |
+----------------------------------------------------------------------------------------------------------------+
| {"id": 2,"labels": ["Alien"],"properties": {"age": 20,"galaxy": "Milky way","name": "Gorlock"},"type": "node"} |
+----------------------------------------------------------------------------------------------------------------+
Now, use the merge.node()
procedure to either merge or create an Alien
node
with the name Zumbi
. If that's a newly created node, the age
property will
be 30, and if it's a merged node, age
will be 40. Additionally, the galaxy
property will be used as an identifying property.
When using merge.node()
procedure or MERGE
clause, if there is no match in
the graph, and a node is created, it will be created with identifying properties
alongside create properties defined by the createProps
input parameter.
CALL merge.node(["Zumbi"],{galaxy: "Andromeda"},{age:20},{age: 40})
YIELD node
RETURN node;
+----------------------------------------------------------------------------------------------------------------+
| node |
+----------------------------------------------------------------------------------------------------------------+
| {"id": 3,"labels": ["Zumbi"],"properties": {"age": 20,"galaxy": "Andromeda"},"type": "node"} |
+----------------------------------------------------------------------------------------------------------------+
A new node was created, because the graph did not contain an Alien
node with the name `Zumbi.
Now, use the merge.node()
procedure to give weapons to all Humans
aged 20.
CALL merge.node(["Zumbi"],{galaxy: "Andromeda"},{age:20},{age: 40}) YIELD node RETURN node;
+---------------------------------------------------------------------------------------------------------------------------------+
| node |
+---------------------------------------------------------------------------------------------------------------------------------+
| {"id": 0,"labels": ["Human"],"properties": {"age": 20,"galaxy": "Milky way","name": "Mark","weapon": "sword"},"type": "node"} |
+---------------------------------------------------------------------------------------------------------------------------------+
Mark
is the only node on the graph that can get a weapon
property.
Finally, let's age every 20-year-old to 25.
CALL merge.node([],{age: 20},{},{age: 25}) YIELD node RETURN node;
+---------------------------------------------------------------------------------------------------------------------------------+
| node |
+---------------------------------------------------------------------------------------------------------------------------------+
| {"id": 0,"labels": ["Human"],"properties": {"age": 25,"galaxy": "Milky way","name": "Mark","weapon": "sword"},"type": "node"} |
+---------------------------------------------------------------------------------------------------------------------------------+
| {"id": 2,"labels": ["Alien"],"properties": {"age": 25,"galaxy": "Milky way","name": "Gorlock"},"type": "node"} |
+---------------------------------------------------------------------------------------------------------------------------------+
| {"id": 33,"labels": ["Zumbi"],"properties": {"age": 25,"galaxy": "Andromeda"},"type": "node"} |
+---------------------------------------------------------------------------------------------------------------------------------+
relationship()
The procedure provides a more flexible way of merging relationships than
Cypher’s MERGE
clause, by allowing labels and properties to be extracted as
results of other procedures and sent as a list or map.
Input:
startNode: Node
➡ The start node of the relationship.relationshipType: string
➡ The relationship type to be matched or created.identProps: Map
➡ A map with key-value pairs used for identifying which relationships will be merged.createProps: Map
➡ A map with key-value pairs which represent properties of the relationship, when the procedure creates a new relationship. Equivalent to usingON CREATE SET
for properties when usingMERGE
.endNode: Node
➡ The end node of the relationship.mergeProps: Map
➡ A map with key-value pairs which represent properties of the relationship, when the procedure merges onto a relationship. Equivalent to usingON MATCH SET
for properties when usingMERGE
.
Output:
rel: Relationship
➡ The relationship which was created or merged in the procedure.
Usage:
Consider a graph with one Human
, two Dog
nodes. Both dogs love the human but
one loves him unconditionally.
CREATE (d:Dog {name: 'Johnny'})-[l:Loves {unconditionally: true}]->(h:Human)
CREATE (c:Dog {name: 'Floki'});
Use merge.relationship()
procedure to add a property called trueLove
to
every Loves
relationship between a human and a dog that has the property
unconditional set to true
. Otherwise, create a new Loves
relationship with
the property unconditionally set to false
.
MATCH (d:Dog)
MATCH (h:Human)
CALL merge.relationship(d, 'Loves', {unconditionally: true}, {unconditionally: false}, h, {trueLove: true})
YIELD rel;
+---------------------------------------------------------------------------------------------------------------------------+
| rel |
+---------------------------------------------------------------------------------------------------------------------------+
| {"id":1,"start":3,"end":4,"label":"Loves","properties":{"trueLove":true,"unconditionally":true},"type":"relationship"} |
+---------------------------------------------------------------------------------------------------------------------------+
| {"id":2,"start":5,"end":4,"label":"Loves","properties":{"unconditionally":false},"type":"relationship"} |
+---------------------------------------------------------------------------------------------------------------------------+