Skip to content

Add docs for OR label expressions #1240

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 16, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 92 additions & 33 deletions pages/querying/clauses/match.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ The `MATCH` clause is used to obtain data from the database by matching it to a
1. [Matching nodes](#1-matching-nodes) <br />
1.1. [Get all nodes](#11-get-all-nodes) <br />
1.2. [Get all nodes with a label](#12-get-all-nodes-with-a-label) <br />
1.3. [Get nodes with with all of multiple labels](#13-get-nodes-with-all-labels) <br />
1.4. [Get nodes with any of multiple labels](#14-get-nodes-with-any-labels) <br />
2. [Matching relationships](#2-matching-relationships) <br />
2.1. [Get all related nodes](#21-get-all-related-nodes) <br />
2.2. [Get related nodes with a label](#22-get-related-nodes-with-a-label) <br />
Expand All @@ -37,12 +39,13 @@ Return it with the [`id()` function](/querying/functions).

</Callout>

## Data Set
## Dataset

The following examples are executed with this data set. You can create this data set
locally by executing the queries at the end of the page: [Dataset queries](#dataset-queries).
The following examples are executed with this dataset. You can replicate this
dataset locally by executing the queries at the end of the page: [Dataset
queries](#dataset-queries).

![Data set](/pages/querying/clauses/data_set.png)
![Schema](/pages/querying/clauses/graph_schema.png)

## 1. Matching nodes

Expand All @@ -63,9 +66,11 @@ Output:
| (:Country {continent: "Europe", language: "German", name: "Germany", population: 83000000}) |
| (:Country {continent: "Europe", language: "French", name: "France", population: 67000000}) |
| (:Country {continent: "Europe", language: "English", name: "United Kingdom", population: 66000000}) |
| (:Person {name: "John"}) |
| (:Person:Employee {name: "John"}) |
| (:Person {name: "Harry"}) |
| (:Person {name: "Anna"}) |
| (:City {name: "Berlin", population: 3600000}) |
| (:City {name: "Paris", population: 2140000}) |
+-----------------------------------------------------------------------------------------------------+
```

Expand All @@ -89,6 +94,58 @@ Output:
+-----------------------------------------------------------------------------------------------------+
```

### 1.3. Get nodes with all labels

If you want to match nodes that have **both** labels (e.g. `:Person` and
`:Employee`), you can use a chained label. This only returns nodes that have
both `Person` and `Employee` labels.

```cypher
MATCH (n:Person:Employee)
RETURN n;
```

Output:
```nocopy
+-----------------------------------+
| n |
+-----------------------------------+
| (:Person:Employee {name: "John"}) |
+-----------------------------------+
```

### 1.4. Get nodes with any of labels

You can use the `OR` (`|`) operator to match nodes that have **any** of the
specified labels:

```cypher
MATCH (n:Country|Person)
RETURN n;
```

Output:
```nocopy
+-----------------------------------------------------------------------------------------------------+
| n |
+-----------------------------------------------------------------------------------------------------+
| (:Country {continent: "Europe", language: "German", name: "Germany", population: 83000000}) |
| (:Country {continent: "Europe", language: "French", name: "France", population: 67000000}) |
| (:Country {continent: "Europe", language: "English", name: "United Kingdom", population: 66000000}) |
| (:Person:Employee {name: "John"}) |
| (:Person {name: "Harry"}) |
| (:Person {name: "Anna"}) |
+-----------------------------------------------------------------------------------------------------+
```

This allows you to retrieve nodes of different types in a single query, making label-based exploration more flexible.

<Callout type="info">

Label OR expressions (`|`) can't be used in `MERGE` or `CREATE` clauses.

</Callout>

## 2. Matching relationships

### 2.1. Get all related nodes
Expand Down Expand Up @@ -145,11 +202,11 @@ RETURN p;

Output:
```nocopy
+--------------------------+
| p |
+--------------------------+
| (:Person {name: "John"}) |
+--------------------------+
+-----------------------------------+
| p |
+-----------------------------------+
| (:Person:Employee {name: "John"}) |
+-----------------------------------+
```

### 2.4. Get a relationship
Expand Down Expand Up @@ -275,13 +332,12 @@ RETURN n;

Output:
```nocopy
+---------------------------------------------------------------------------------------------+
| n |
+---------------------------------------------------------------------------------------------+
| (:Person {name: "Harry"}) |
| (:Person {name: "Anna"}) |
| (:Country {continent: "Europe", language: "German", name: "Germany", population: 83000000}) |
+---------------------------------------------------------------------------------------------+
+---------------------------+
| n |
+---------------------------+
| (:Person {name: "Harry"}) |
| (:Person {name: "Anna"}) |
+---------------------------+
```

### 3.2. Variable length relationships with multiple relationship types
Expand All @@ -295,13 +351,13 @@ RETURN p;

Output:
```nocopy
+---------------------------+
| p |
+---------------------------+
| (:Person {name: "John"}) |
| (:Person {name: "Harry"}) |
| (:Person {name: "Anna"}) |
+---------------------------+
+-----------------------------------+
| p |
+-----------------------------------+
| (:Person {name: "Harry"}) |
| (:Person:Employee {name: "John"}) |
| (:Person {name: "Anna"}) |
+-----------------------------------+
```

### 3.3. Returning multiple relationships with variable length
Expand Down Expand Up @@ -396,13 +452,7 @@ RETURN names;

Output:

```nocopy
+-------+
| names |
+-------+
| Null |
+-------+
```
`Empty set`

Since the dataset doesn't contain any nodes labeled as `Country` with a property `continent` with the value `Asia`, the second `MATCH` clause returns an empty dataset and therefore the output is also an empty list. To avoid getting an empty list as an output, due to any of the `MATCH` clauses returning an empty set, use `OPTIONAL MATCH` clause:

Expand All @@ -426,7 +476,7 @@ Output:

The `OPTIONAL MATCH` clause bypasses the empty set and the query returns only non-empty sets. Therefore, the output of the query is a list containing only the results of the first `MATCH` clause.

## Dataset Queries
## Dataset queries

We encourage you to try out the examples by yourself.
You can get our data set locally by executing the following query block.
Expand All @@ -440,7 +490,7 @@ CREATE (c3:Country {name: 'United Kingdom', language: 'English', continent: 'Eur

MATCH (c1),(c2)
WHERE c1.name = 'Germany' AND c2.name = 'France'
CREATE (c2)<-[:WORKING_IN {date_of_start: 2014}]-(p:Person {name: 'John'})-[:LIVING_IN {date_of_start: 2014}]->(c1);
CREATE (c2)<-[:WORKING_IN {date_of_start: 2014}]-(p:Person:Employee {name: 'John'})-[:LIVING_IN {date_of_start: 2014}]->(c1);

MATCH (c)
WHERE c.name = 'United Kingdom'
Expand All @@ -458,5 +508,14 @@ MATCH (p),(c1),(c2)
WHERE p.name = 'Anna' AND c1.name = 'United Kingdom' AND c2.name = 'Germany'
CREATE (c2)<-[:LIVING_IN {date_of_start: 2014}]-(p)-[:LIVING_IN {date_of_start: 2014}]->(c1);

CREATE (city1:City {name: 'Berlin', population: 3600000});
CREATE (city2:City {name: 'Paris', population: 2140000});

MATCH (city1:City {name: 'Berlin'}), (country1:Country {name: 'Germany'})
CREATE (city1)-[:LOCATED_IN]->(country1);

MATCH (city2:City {name: 'Paris'}), (country2:Country {name: 'France'})
CREATE (city2)-[:LOCATED_IN]->(country2);

MATCH (n)-[r]->(m) RETURN n,r,m;
```
2 changes: 0 additions & 2 deletions pages/querying/differences-in-cypher-implementations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,6 @@ using `OPTIONAL` expansions, function calls, etc.
- Numerical:
- An octal `INTEGER` literal (starting with `0o`): `0o1372`, `0o5671`
- A `FLOAT` literal: `Inf`, `Infinity`, `NaN`
- Boolean:
- Label expressions: `(n:A|B)` -> Track progress on [GitHub](https://github.com/memgraph/memgraph/issues/1848) and add a comment if you require such a feature.

{<h4 className="custom-header">Conditional expressions (<code>CASE</code>)</h4>}
- More than one value after `WHEN` operator:
Expand Down
Binary file added public/pages/querying/clauses/graph_schema.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.