# node

The `node` module provides a comprehensive toolkit for managing graph nodes, enabling creation, deletion, updating, merging, and more.

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

### `relationship_types()`

The procedure returns a list of distinct relationship types of the given node
contained within the given list of types. If the list of types is empty returns
all distinct relationship types. Relationship types can also be directed:
- &lt;type - incoming relationship.
- type> - outgoing relationship.
- type - either way.

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

- `node: Node` ➡ The given node.
- `types: List[string] (default = [])` ➡ A list of relationship types to filter by.

#### Output:

- `relationship_types: List[string]` ➡ A list of distinct relationship types contained within the given list of types.

#### Usage:

The database contains the following graph objects:

```cypher
CREATE (ivan: Intern {name: 'Ivan'})
CREATE (idora: Intern {name: 'Idora'})
CREATE (matija: Intern {name: 'Matija'})
MERGE (ivan)-[:KNOWS]->(idora)
MERGE (matija)-[:HEARS]->(idora)
MERGE (matija)-[:SEES]->(ivan);
```

To get the relationship types, run the following query:

```cypher
MATCH (intern:Intern) 
CALL node.relationship_types(intern, ["<KNOWS", "SEES>", "HEARS"]) 
YIELD relationship_types 
RETURN intern.name as name, relationship_types;
```

Results:

```plaintext
+--------------------------------+
| name      relationship_types   |
+--------------------------------+
| Ivan      []                   |
+--------------------------------+
| Idora     ["HEARS", "KNOWS"]   |
+--------------------------------+
| Matija    ["SEES", "HEARS"]    |
+--------------------------------+
```

### `relationship_exists()`

The procedure checks if the given node has a relationship of a specific type.  

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

- `node: Node` ➡ The target node for which the existence of a relationship type is verified.
- `pattern: List[string] (optional)` ➡ A list of relationship types that need to be checked. If the input parameter is empty, procedure will check all types of relationships.

If &lt; is added in front of the relationship type, only relationships coming
into the node will be checked (e.g., "&lt;KNOWS"), while if > is added at the
end of the relationship type, only relationships coming from the node will be
checked (e.g., "KNOWS>"). Furthermore, if relationship type is not relevant, it
is possible to enter only &lt; or > to check incoming or outgoing relationships.

#### Output:

- `exists: bool` ➡ Whether or not thr provided node has a relationship of the specified type.

#### Usage:

The database contains the following graph objects:

```cypher
MERGE (a:Person {name: "Phoebe"})
MERGE (b:Person {name: "Joey"})
CREATE (a)-[f:FRIENDS]->(b);
MATCH (a:Person {name: "Joey"})
```

To check the existence of a relationship type `FRIENDS` coming to the node `a`,
run the following query:

```
CALL node.relationship_exists(a, ["<FRIENDS"]) 
YIELD exists
RETURN exists;
```

Result: 

```plaintext
+----------------------------+
| exists                     |
+----------------------------+
| True                       |
+----------------------------+
```

### `relationships_exist()`

The procedure checks if relationships in the input list exist at the given node. Results are
returned as a map, represented as string-bool pair, where string represents the
relationship, and bool represents if the relationship exists or not.
Relationships can be directed, and the syntax for direction specification is
provided below:
- &lt;type - incoming relationship.
- type> - outgoing relationship.
- type - both incoming and outgoing.
- anything else results in an exception.

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

- `node: Node` ➡ The target node for which the existence of relationship types is verified.
- `relationships: List[string]` ➡ A list of relationship types that need to be
  checked. If the input parameter is empty, procedure will check all types of
  relationships.

#### Output:

- `result: Map` ➡ A map of string-bool pairs, where string represents a
  relationship, and bool represents if the relationship exist or not. For
  example: `{rel1: true, rel2>: false}` means `rel1` exists, and outgoing `rel2`
  doesn't exist.

#### Usage:

The database contains the following graph objects:

```cypher
CREATE (d:Dog)-[l:LOVES]->(h:Human)-[t:TAKES_CARE_OF]->(d);
```

To check the existence of various relationship types related to node `d`,
run the following query:

```cypher
MATCH (d:Dog) 
CALL node.relationships_exist(d, ["LOVES>", "TAKES_CARE_OF", "FOLLOWS", "<LOVES"]) 
YIELD result 
RETURN result;
```

Result:

```plaintext
+----------------------------------------------------------------------------+
| result                                                                     |
+----------------------------------------------------------------------------+
| {"<LOVES": false, "FOLLOWS": false, "LOVES>": true, "TAKES_CARE_OF": true} |                  
+----------------------------------------------------------------------------+
```

To check the existence of various relationship types related to node `h`,
run the following query:

```cypher
MATCH (h:Human) CALL node.relationships_exist(h, ["LOVES>", "TAKES_CARE_OF", "FOLLOWS", "<LOVES"]) YIELD result RETURN result;
```

Result: 

```plaintext
+----------------------------------------------------------------------------+
| result                                                                     |
+----------------------------------------------------------------------------+
| {"<LOVES": true, "FOLLOWS": false, "LOVES>": false, "TAKES_CARE_OF": true} |                  
+----------------------------------------------------------------------------+
```

## Functions

### `degree_in()`

Returns the in degree of the input node. If the value of the input parameter
`type` is set, only relationships with the type specified will be counted for
node degree.

#### Input:

- `node: Node` ➡ The input node.
- `type: string, default = ""` ➡ Optionally, you can define the relationship type which will be counted for degree calculation.

#### Output:

An integer that represents the node in degree value.

#### Usage:

The database contains the following graph objects:

```cypher
CREATE (d:Dog),(h:Human),(d)-[l:LOVES]->(h),(d)-[o:OWNED_BY]->(h);
```

Use the following query to calculate the node degree of node `h` regardless of
the relationship type:

```cypher
MATCH (h:Human) 
RETURN node.degree_in(h) AS result;
```

Result:

```plaintext
+----------------------------------------------------------------------------+
| result                                                                     |
+----------------------------------------------------------------------------+
| 2                                                                          |                  
+----------------------------------------------------------------------------+
```

Use the following query to calculate the node degree of node `h` considering
only relationships of type `LOVES`:

```cypher
MATCH (h:Human)
RETURN node.degree_in(h, "LOVES") AS result;
```

Result: 

```plaintext
+----------------------------------------------------------------------------+
| result                                                                     |
+----------------------------------------------------------------------------+
| 1                                                                          |                  
+----------------------------------------------------------------------------+
```

### `degree_out()`

Returns the out degree of the input node. If the value of the input parameter
`type` is set, only relationships with the type specified will be counted for
node degree.

#### Input:

- `node: Node` ➡ The input node.
- `type: string, default = ""` ➡ Optionally, you can define the relationship type which will be counted for degree calculation.

#### Output:

An integer that represents the node out degree value.

#### Usage:

The database contains the following graph objects:

```cypher
CREATE (d:Dog),(h:Human),(d)-[l:LOVES]->(h),(d)-[o:OWNED_BY]->(h);
```

Use the following query to calculate the out degree of node `d` regardless of
the relationship type:

```cypher
MATCH (d:Dog) 
RETURN node.degree_out(d) AS result;
```

Result:

```plaintext
+----------------------------------------------------------------------------+
| result                                                                     |
+----------------------------------------------------------------------------+
| 2                                                                          |                  
+----------------------------------------------------------------------------+
```

Use the following query to calculate the out degree of node `d` considering
only relationships of type `LOVES`:

```cypher
MATCH (d:Dog) 
RETURN node.degree_out(d, "LOVES") AS result;
```

Result:

```plaintext
+----------------------------------------------------------------------------+
| result                                                                     |
+----------------------------------------------------------------------------+
| 1                                                                          |                  
+----------------------------------------------------------------------------+
```
