# 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

> **Info**
>
> You can execute this algorithm on [graph projections, subgraphs or portions of the graph](https://memgraph.com/docs/advanced-algorithms/run-algorithms#run-procedures-on-subgraph).

### `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](https://memgraph.com/docs/advanced-algorithms/run-algorithms#run-procedures-on-subgraph) returned by the `project()` 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 using `ON CREATE SET` for properties when using `MERGE`.
- `mergeProps: Map` ➡ A map with key-value pairs which represent properties of the node, when the procedure merges onto a node.
Equivalent to using `ON MATCH SET` for properties when using `MERGE`.

#### Output:

- `node: Node` ➡ The node which was created or merged in the procedure.

#### Usage:

Consider a graph with two `Human`, and one `Alien` node.

```cypher
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.

```cypher
CALL merge.node([],{},{},{galaxy: "Milky way"}) 
YIELD node 
RETURN node;
```

```plaintext
+----------------------------------------------------------------------------------------------------------------+
| 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.

```cypher
CALL merge.node(["Zumbi"],{galaxy: "Andromeda"},{age:20},{age: 40}) 
YIELD node 
RETURN node;
```

```plaintext
+----------------------------------------------------------------------------------------------------------------+
| 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.

```cypher
CALL merge.node(["Zumbi"],{galaxy: "Andromeda"},{age:20},{age: 40}) YIELD node RETURN node;
```

```plaintext
+---------------------------------------------------------------------------------------------------------------------------------+
| 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.

```cypher
CALL merge.node([],{age: 20},{},{age: 25}) YIELD node RETURN node;
```

```plaintext
+---------------------------------------------------------------------------------------------------------------------------------+
| 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:

- `subgraph: Graph` (**OPTIONAL**) ➡ A specific subgraph, which is an [object of type Graph](https://memgraph.com/docs/advanced-algorithms/run-algorithms#run-procedures-on-subgraph) returned by the `project()` function, on which the algorithm is run. 
If subgraph is not specified, the algorithm is computed on the entire graph by default.
- `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 using `ON CREATE SET` for properties when using `MERGE`.
- `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 using `ON MATCH SET` for properties when using `MERGE`.

#### 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.

```cypher
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`.

```cypher
MATCH (d:Dog)
MATCH (h:Human) 
CALL merge.relationship(d, 'Loves', {unconditionally: true}, {unconditionally: false}, h, {trueLove: true}) 
YIELD rel;
```

```plaintext
+---------------------------------------------------------------------------------------------------------------------------+
| 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"}                   |
+---------------------------------------------------------------------------------------------------------------------------+
```
