Expressions

This section contains an overview of expressions in Cypher with examples.

Expressions in general

Most expressions in Cypher evaluate to null if any of their inner expressions are null. Notable exceptions are the operators IS NULL and IS NOT NULL.

An expression in Cypher can be:

  • A decimal (integer or float) literal: 13, -40000, 3.14.

  • A decimal (integer or float) literal in scientific notation: 6.022E23.

  • A hexadecimal integer literal (starting with 0x): 0x13af, 0xFC3A9, -0x66eff.

  • An octal integer literal (starting with 0o): 0o1372, -0o5671.

  • A string literal: 'Hello', "World".

  • A float literal: Inf, Infinity, NaN

  • A boolean literal: true, false.

  • A variable: n, x, rel, myFancyVariable, `A name with weird stuff in it[]!`.

  • A property: n.prop, x.prop, rel.thisProperty, myFancyVariable.`(weird property name)`.

  • A dynamic property: n["prop"], rel[n.city + n.zip], map[coll[0]].

  • A parameter: $param, $0.

  • A list of expressions: ['a', 'b'], [1, 2, 3], ['a', 2, n.property, $param], [].

  • A function call: length(p), nodes(p).

  • An aggregate function: avg(x.prop), count(*).

  • A path-pattern: (a)-[r]->(b), (a)-[r]-(b), (a)--(b), (a)-->()<--(b).

  • An operator application: 1 + 2, 3 < 4.

  • A predicate expression is an expression that returns true or false: a.prop = 'Hello', length(p) > 10, a.name IS NOT NULL.

  • A special case of predicates are label and relationship type expressions: (n:A|B), ()-[r:R1|R2]→().

  • A subquery expression. For example: EXISTS { MATCH (n)-[r]→(p) WHERE p.name = 'Sven' }.

  • A regular expression: a.name =~ 'Tim.*'.

  • A case-sensitive string matching expression: a.surname STARTS WITH 'Sven', a.surname ENDS WITH 'son' or a.surname CONTAINS 'son'.

  • A CASE expression.

Note on string literals

String literals can contain the following escape sequences:

Escape sequence Character

\t

Tab

\b

Backspace

\n

Newline

\r

Carriage return

\f

Form feed

\'

Single quote

\"

Double quote

\\

Backslash

\uxxxx

Unicode UTF-16 code point (4 hex digits must follow the \u)

Using regular expressions with unsanitized user input makes you vulnerable to Cypher injection. Consider using parameters instead.

Note on number literals

Any number literal may contain an underscore _ between digits. There may be an underscore between the 0x or 0o and the digits for hexadecimal and octal literals.

CASE expressions

Generic conditional expressions may be expressed using the CASE construct. Two variants of CASE exist within Cypher: the simple form, which allows an expression to be compared against multiple values, and the generic form, which allows multiple conditional statements to be expressed.

CASE can only be used as part of RETURN or WITH if you want to use the result in the succeeding clause or statement.

The following graph is used for the examples below:

graph3

Simple CASE form: comparing an expression against multiple values

The expression is calculated, and compared in order with the WHEN clauses until a match is found. If no match is found, the expression in the ELSE clause is returned. However, if there is no ELSE case and no match is found, null will be returned.

CASE test
  WHEN value THEN result
  [WHEN ...]
  [ELSE default]
END

Arguments:

Name Description

test

A valid expression.

value

An expression whose result will be compared to test.

result

This is the expression returned as output if value matches test.

default

If no match is found, default is returned.

Query
MATCH (n)
RETURN
CASE n.eyes
  WHEN 'blue'  THEN 1
  WHEN 'brown' THEN 2
  ELSE 3
END AS result
Table 1. Result
result

2

1

3

2

1

Rows: 5

Generic CASE form: allowing for multiple conditionals to be expressed

The predicates are evaluated in order until a true value is found, and the result value is used. If no match is found, the expression in the ELSE clause is returned. However, if there is no ELSE case and no match is found, null will be returned.

CASE
  WHEN predicate THEN result
  [WHEN ...]
  [ELSE default]
END

Arguments:

Name Description

predicate

A predicate that is tested to find a valid alternative.

result

This is the expression returned as output if predicate evaluates to true.

default

If no match is found, default is returned.

Query
MATCH (n)
RETURN
CASE
  WHEN n.eyes = 'blue' THEN 1
  WHEN n.age < 40      THEN 2
  ELSE 3
END AS result
Table 2. Result
result

2

1

3

3

1

Rows: 5

Distinguishing between when to use the simple and generic CASE forms

Owing to the close similarity between the syntax of the two forms, sometimes it may not be clear at the outset as to which form to use. We illustrate this scenario by means of the following query, in which there is an expectation that age_10_years_ago is -1 if n.age is null:

Query
MATCH (n)
RETURN n.name,
CASE n.age
  WHEN n.age IS NULL THEN -1
  ELSE n.age - 10
END AS age_10_years_ago

However, as this query is written using the simple CASE form, instead of age_10_years_ago being -1 for the node named Daniel, it is null. This is because a comparison is made between n.age and n.age IS NULL. As n.age IS NULL is a boolean value, and n.age is an integer value, the WHEN n.age IS NULL THEN -1 branch is never taken. This results in the ELSE n.age - 10 branch being taken instead, returning null.

Table 3. Result
n.name age_10_years_ago

"Alice"

28

"Bob"

15

"Charlie"

43

"Daniel"

<null>

"Eskil"

31

Rows: 5

The corrected query, behaving as expected, is given by the following generic CASE form:

Query
MATCH (n)
RETURN n.name,
CASE
  WHEN n.age IS NULL THEN -1
  ELSE n.age - 10
END AS age_10_years_ago

We now see that the age_10_years_ago correctly returns -1 for the node named Daniel.

Table 4. Result
n.name age_10_years_ago

"Alice"

28

"Bob"

15

"Charlie"

43

"Daniel"

-1

"Eskil"

31

Rows: 5

Using the result of CASE in the succeeding clause or statement

You can use the result of CASE to set properties on a node or relationship. For example, instead of specifying the node directly, you can set a property for a node selected by an expression:

Query
MATCH (n)
WITH n,
CASE n.eyes
  WHEN 'blue'  THEN 1
  WHEN 'brown' THEN 2
  ELSE 3
END AS colourCode
SET n.colourCode = colourCode

For more information about using the SET clause, see SET.

Table 5. Result

(empty result)

Rows: 0
Properties set: 5

Using CASE with null values

When using the simple CASE form, it is useful to remember that in Cypher null = null yields null.

Example 1. CASE

For example, you might expect age_10_years_ago to be -1 for the node named Daniel:

Query
MATCH (n)
RETURN n.name,
CASE n.age
  WHEN null THEN -1
  ELSE n.age - 10
END AS age_10_years_ago

However, as null = null does not yield true, the WHEN null THEN -1 branch is never taken, resulting in the ELSE n.age - 10 branch being taken instead, returning null.

Table 6. Result
n.name age_10_years_ago

"Alice"

28

"Bob"

15

"Charlie"

43

"Daniel"

<null>

"Eskil"

31

Rows: 5

Subquery expressions

Subquery expressions can appear anywhere that an expression is valid. A subquery has a scope, as indicated by the opening and closing braces, { and }. Any variable that is defined in the outside scope can be referenced inside the subquery’s own scope. Variables introduced inside the subquery are not part of the outside scope and therefore can’t be accessed on the outside.

The following graph is used for the examples below:

graph expression subqueries

EXISTS subqueries

An EXISTS subquery can be used to find out if a specified pattern exists at least once in the data. It serves the same purpose as a path pattern but is more powerful because it allows you to use MATCH and WHERE clauses internally. Moreover, it can appear in any expression position, unlike path patterns. If the subquery evaluates to at least one row, the whole expression will become true. This also means that the system only needs to evaluate if there is at least one row and can skip the rest of the work.

Any non-writing query is allowed. EXISTS subqueries differ from regular queries in that the final RETURN clause may be omitted, as any variable defined within the subquery will not be available outside of the expression, even if a final RETURN clause is used.

It is worth noting that the MATCH keyword can be omitted in subqueries in cases where the EXISTS consists of only a pattern and an optional WHERE clause.

Simple EXISTS subquery

Variables introduced by the outside scope can be used in the EXISTS subquery without importing them. In this regard, EXISTS subqueries are different from CALL subqueries, which do require importing. The following example shows this:

Query
MATCH (person:Person)
WHERE EXISTS {
    (person)-[:HAS_DOG]->(:Dog)
}
RETURN person.name AS name
Table 7. Result
name

"Andy"

"Peter"

Rows: 2

EXISTS subquery with WHERE clause

A WHERE clause can be used in conjunction to the MATCH. Variables introduced by the MATCH clause and the outside scope can be used in this scope.

Query
MATCH (person:Person)
WHERE EXISTS {
  MATCH (person)-[:HAS_DOG]->(dog:Dog)
  WHERE person.name = dog.name
}
RETURN person.name AS name
Table 8. Result
name

"Andy"

Rows: 1

Nesting EXISTS subqueries

EXISTS subqueries can be nested like the following example shows. The nesting also affects the scopes. That means that it is possible to access all variables from inside the subquery which are either from the outside scope or defined in the very same subquery.

Query
MATCH (person:Person)
WHERE EXISTS {
  MATCH (person)-[:HAS_DOG]->(dog:Dog)
  WHERE EXISTS {
    MATCH (dog)-[:HAS_TOY]->(toy:Toy)
    WHERE toy.name = 'Banana'
  }
}
RETURN person.name AS name
Table 9. Result
name

"Peter"

Rows: 1

EXISTS subquery outside of a WHERE clause

EXISTS subquery expressions can appear anywhere that an expression is valid. Here the result is a boolean that shows whether the subquery can find the given pattern.

Query
MATCH (person:Person)
RETURN person.name AS name, EXISTS {
  MATCH (person)-[:HAS_DOG]->(:Dog)
} AS hasDog
Table 10. Result
name hasDog

"Andy"

true

"Timothy"

false

"Peter"

true

Rows: 3

EXISTS subquery with a UNION

Exists can be used with a UNION clause, and the RETURN clauses are not required. It is worth noting that if one branch has a RETURN clause, then all branches require one. The below example demonstrates that if one of the UNION branches was to return at least one row, the entire EXISTS expression will evaluate to true.

Query
MATCH (person:Person)
RETURN
    person.name AS name,
    EXISTS {
        MATCH (person)-[:HAS_DOG]->(:Dog)
        UNION
        MATCH (person)-[:HAS_CAT]->(:Cat)
    } AS hasPet
Table 11. Result
name hasPet

"Andy"

true

"Timothy"

true

"Peter"

true

Rows: 3

EXISTS subquery with WITH

Variables from the outside scope are visible for the entire subquery, even when using a WITH clause. This means that shadowing of these variables is not allowed. An outside scope variable is shadowed when a newly introduced variable within the inner scope is defined with the same variable. In the below example, a WITH clause introduces a new variable. Note that the outer scope variable person referenced in the main query is still available after the WITH clause.

Query
MATCH (person:Person)
WHERE EXISTS {
    WITH "Ozzy" AS dogName
    MATCH (person)-[:HAS_DOG]->(d:Dog)
    WHERE d.name = dogName
}
RETURN person.name AS name
Table 12. Result
name

"Peter"

Rows: 1

EXISTS subquery with RETURN

EXISTS subqueries do not require a RETURN clause at the end of the subquery. If one is present, it does not need to be aliased, which is different compared to CALL subqueries. Any variables returned in an EXISTS subquery will not be available after the subquery.

Query
MATCH (person:Person)
WHERE EXISTS {
    MATCH (person)-[:HAS_DOG]->(:Dog)
    RETURN person.name
}
RETURN person.name AS name
Table 13. Result
name

"Andy"

"Peter"

Rows: 2

COUNT subqueries

A COUNT subquery expression can be used to count the number of rows returned by the subquery.

Any non-writing query is allowed. COUNT subqueries differ from regular queries in that the final RETURN clause may be omitted, as any variable defined within the subquery will not be available outside of the expression, even if a final RETURN clause is used. One exception to this is that for a DISTINCT UNION clause, the RETURN clause is still mandatory.

It is worth noting that the MATCH keyword can be omitted in subqueries in cases where the COUNT consists of only a pattern and an optional WHERE clause.

Simple COUNT subquery

Variables introduced by the outside scope can be used in the COUNT subquery without importing them. In this regard, COUNT subqueries are different from CALL subqueries, which do require importing. The following query exemplifies this and outputs the owners of more than one dog:

Query
MATCH (person:Person)
WHERE COUNT { (person)-[:HAS_DOG]->(:Dog) } > 1
RETURN person.name AS name
Table 14. Result
name

"Peter"

Rows: 1

COUNT subquery with WHERE clause

A WHERE clause can be used inside the COUNT pattern. Variables introduced by the MATCH clause and the outside scope can be used in this scope.

Query
MATCH (person:Person)
WHERE COUNT {
  (person)-[:HAS_DOG]->(dog:Dog)
  WHERE person.name = dog.name
} = 1
RETURN person.name AS name
Table 15. Result
name

"Andy"

Rows: 1

COUNT subquery with a UNION

COUNT can be used with a UNION clause. If the UNION clause is distinct, the RETURN clause is required. UNION ALL clauses do not require the RETURN clause. However, it is worth noting that if one branch has a RETURN clause, then all require one. The below example shows the count of pets each person has by using a UNION clause:

Query
MATCH (person:Person)
RETURN
    person.name AS name,
    COUNT {
        MATCH (person)-[:HAS_DOG]->(dog:Dog)
        RETURN dog.name AS petName
        UNION
        MATCH (person)-[:HAS_CAT]->(cat:Cat)
        RETURN cat.name AS petName
    } AS numPets
Table 16. Result
name numPets

"Andy"

1

"Timothy"

1

"Peter"

2

Rows: 3

COUNT subquery with WITH

Variables from the outside scope are visible for the entire subquery, even when using a WITH clause. This means that shadowing of these variables is not allowed. An outside scope variable is shadowed when a newly introduced variable within the inner scope is defined with the same variable. In the below example, a WITH clause introduces a new variable. Note that the outer scope variable person referenced in the main query is still available after the WITH clause.

Query
MATCH (person:Person)
WHERE COUNT {
    WITH "Ozzy" AS dogName
    MATCH (person)-[:HAS_DOG]->(d:Dog)
    WHERE d.name = dogName
} = 1
RETURN person.name AS name
Table 17. Result
name

"Peter"

Rows: 1

Using COUNT subqueries inside other clauses

COUNT can be used in any position in a query, with the exception of administration commands, where it is restricted. See a few examples below:

Using COUNT in RETURN
Query
MATCH (person:Person)
RETURN person.name, COUNT { (person)-[:HAS_DOG]->(:Dog) } as howManyDogs
Table 18. Result
person.name howManyDogs

"Andy"

1

"Timothy"

0

"Peter"

2

Rows: 3

Using COUNT in SET
Query
MATCH (person:Person) WHERE person.name ="Andy"
SET person.howManyDogs = COUNT { (person)-[:HAS_DOG]->(:Dog) }
RETURN person.howManyDogs as howManyDogs
Table 19. Result
howManyDogs

1

Rows: 1
Properties set: 1

Using COUNT in CASE
Query
MATCH (person:Person)
RETURN
   CASE
     WHEN COUNT { (person)-[:HAS_DOG]->(:Dog) } > 1 THEN "Doglover " + person.name
     ELSE person.name
   END AS result
Table 20. Result
result

"Andy"

"Timothy"

"Doglover Peter"

Rows: 3

Using COUNT as a grouping key

The following query groups all persons by how many dogs they own, and then calculates the average age for each group.

Query
MATCH (person:Person)
RETURN COUNT { (person)-[:HAS_DOG]->(:Dog) } AS numDogs,
       avg(person.age) AS averageAge
 ORDER BY numDogs
Table 21. Result
numDogs averageAge

0

25.0

1

36.0

2

35.0

Rows: 3

COUNT subquery with RETURN

COUNT subqueries do not require a RETURN clause at the end of the subquery. If one is present, it does not need to be aliased. This is a difference compared to from CALL subqueries. Any variables returned in a COUNT subquery will not be available after the subquery.

Query
MATCH (person:Person)
WHERE COUNT {
    MATCH (person)-[:HAS_DOG]->(:Dog)
    RETURN person.name
} = 1
RETURN person.name AS name
Table 22. Result
name

"Andy"

Rows: 1

COLLECT subqueries

A COLLECT subquery expression can be used to create a list with the rows returned by a given subquery.

Any non-writing query is allowed. COLLECT subqueries differ from COUNT and EXISTS subqueries in that the final RETURN clause is mandatory. The RETURN clause must return exactly one column.

Simple COLLECT subquery

Variables introduced by the outside scope can be used in the COLLECT subquery without importing them. In this regard, COLLECT subqueries are different from CALL subqueries, which do require importing. The following query exemplifies this and outputs the owners of the dog named Ozzy:

Query
MATCH (person:Person)
WHERE 'Ozzy' IN COLLECT { MATCH (person)-[:HAS_DOG]->(dog:Dog) RETURN dog.name }
RETURN person.name AS name
Table 23. Result
name

"Peter"

Rows: 1

COLLECT subquery with WHERE clause

A WHERE clause can be used inside the COLLECT pattern. Variables introduced by the MATCH clause and the outside scope can be used in the inner scope.

Query
MATCH (person:Person)
RETURN person.name as name, COLLECT {
  MATCH (person)-[r:HAS_DOG]->(dog:Dog)
  WHERE r.since > 2017
  RETURN dog.name
} as youngDogs
Table 24. Result
name youngDogs

"Andy"

[]

"Timothy"

[]

"Peter"

["Ozzy"]

Rows: 3

COLLECT subquery with a UNION

COLLECT can be used with a UNION clause. The below example shows the collection of pet names each person has by using a UNION clause:

Query
MATCH (person:Person)
RETURN
    person.name AS name,
    COLLECT {
        MATCH (person)-[:HAS_DOG]->(dog:Dog)
        RETURN dog.name AS petName
        UNION
        MATCH (person)-[:HAS_CAT]->(cat:Cat)
        RETURN cat.name AS petName
    } AS petNames
Table 25. Result
name petNames

"Andy"

["Andy"]

"Timothy"

["Mittens"]

"Peter"

["Ozzy", "Fido"]

Rows: 3

COLLECT subquery with WITH

Variables from the outside scope are visible for the entire subquery, even when using a WITH clause. This means that shadowing of these variables is not allowed. An outside scope variable is shadowed when a newly introduced variable within the inner scope is defined with the same variable. In the below example, the outer variable name is shadowed and will therefore throw an error.

Query
WITH 'Peter' as name
MATCH (person:Person {name: name})
RETURN COLLECT {
    WITH 'Ozzy' AS name
    MATCH (person)-[r:HAS_DOG]->(d:Dog {name: name})
    RETURN d.name
} as dogsOfTheYear
Error message
The variable `name` is shadowing a variable with the same name from the outer scope and needs to be renamed (line 4, column 20 (offset: 92))

New variables can be introduced into the subquery, as long as they use a different identifier. In the below example, a WITH clause introduces a new variable. Note that the outer scope variable person referenced in the main query is still available after the WITH clause.

Query
MATCH (person:Person)
RETURN person.name AS name, COLLECT {
    WITH 2018 AS yearOfTheDog
    MATCH (person)-[r:HAS_DOG]->(d:Dog)
    WHERE r.since = yearOfTheDog
    RETURN d.name
} as dogsOfTheYear
Table 26. Result
name dogsOfTheYear

"Andy"

[]

"Timothy"

[]

"Peter"

["Ozzy"]

Rows: 3

Using COLLECT subqueries inside other clauses

COLLECT can be used in any position in a query, with the exception of administration commands, where the COLLECT expression is restricted. See a few examples below of how COLLECT can be used in different positions within a query:

Using COLLECT in RETURN
Query
MATCH (person:Person)
RETURN person.name,
       COLLECT {
            MATCH (person)-[:HAS_DOG]->(d:Dog)
            MATCH (d)-[:HAS_TOY]->(t:Toy)
            RETURN t.name
       } as toyNames
Table 27. Result
person.name toyNames

"Andy"

[]

"Timothy"

[]

"Peter"

["Banana"]

Rows: 3

Using COLLECT in SET
Query
MATCH (person:Person) WHERE person.name = "Peter"
SET person.dogNames = COLLECT { MATCH (person)-[:HAS_DOG]->(d:Dog) RETURN d.name }
RETURN person.dogNames as dogNames
Table 28. Result
dogNames

["Ozzy", "Fido"]

Rows: 1
Properties set: 1

Using COLLECT in CASE
Query
MATCH (person:Person)
RETURN
   CASE
     WHEN COLLECT { MATCH (person)-[:HAS_DOG]->(d:Dog) RETURN d.name } = []  THEN "No Dogs " + person.name
     ELSE person.name
   END AS result
Table 29. Result
result

"Andy"

"No Dogs Timothy"

"Peter"

Rows: 3

Using COLLECT as a grouping key

The following query collects all persons by their dogs' names, and then calculates the average age for each group.

Query
MATCH (person:Person)
RETURN COLLECT { MATCH (person)-[:HAS_DOG]->(d:Dog) RETURN d.name } AS dogNames,
       avg(person.age) AS averageAge
 ORDER BY dogNames
Table 30. Result
dogNames averageAge

[]

25.0

["Andy"]

36.0

["Ozzy", "Fido"]

35.0

Rows: 3

Using COLLECT vs collect()

COLLECT does not handle null values in the same way that function collect() does. The collect() function automatically removes null values. COLLECT will not remove null values automatically. However, they can be removed by adding a filtering step in the subquery.

The following queries illustrate these differences:

Query
MATCH (p:Person)
RETURN collect(p.nickname) AS names
Table 31. Result
names

["Pete", "Tim"]

Rows: 1

Query
RETURN COLLECT {
        MATCH (p:Person)
        RETURN p.nickname ORDER BY p.nickname
      } AS names
Table 32. Result
names

["Pete", "Tim", null]

Rows: 1

Query
RETURN COLLECT {
        MATCH (p:Person)
        WHERE p.nickname IS NOT NULL
        RETURN p.nickname ORDER BY p.nickname
      } AS names
Table 33. Result
name

["Pete", "Tim"]

Rows: 1

Label expressions

In earlier versions of Neo4j, label expressions for nodes had a single colon operator that represented the AND operator. With the release of version 5, a new label expression with an extended set of logical operators is being introduced, in addition to the single colon operator. It is important to note that you cannot mix these different types of label expression syntax. For more information, see Restrictions on using the different types of label expression syntax.

Label expressions evaluate to true or false when applied to the set of labels for a node.

Assuming no other filters are applied, then a label expression evaluating to true means the node is matched.

The following table displays whether the label expression matches the relationship:

Table 34. Label expression matches

Node

Label expression

()

(:A)

(:B)

(:C)

(:A:B)

(:A:C)

(:B:C)

(:A:B:C)

()

(:A)

(:A&B)

(:A|B)

(:!A)

(:!!A)

(:A&!A)

(:A|!A)

(:%)

(:!%)

(:%|!%)

(:%&!%)

(:A&%)

(:A|%)

(:(A&B)&!(B&C))

(:!(A&%)&%)

Restrictions on using the different types of label expression syntax

Neo4j version 5 introduces an ampersand operator, which is equivalent to the colon conjunction operator. Mixing the colon conjunction operator with any of the new label expression operators in the same clause will raise a syntax error.

For example, each of the following clauses will raise syntax errors:

  • MATCH (n:A|B:C)

  • MATCH (n:A:B)-[]-(m:(A&B)|C)

  • MATCH (n:A:B)--(m), (n)-→(o:(A&B)|C)

  • RETURN n:A&B, n:A:B

  • MATCH (n:A:B)-[]-(m) WHERE m:(A&B)|C

In earlier versions of Neo4j (version 4.4 and earlier), relationship type expressions only had the pipe operator. As the pipe operator will continue to act as an OR operator, it can continue to be used alongside the new operators.

To make it easier to use the new syntax when extending existing queries, using the different syntax types in separate clauses will be supported.

For example, the following query will not raise a syntax error:

MATCH (m:A:B:C)-[]->()
MATCH (n:(A&B)|C)-[]->(m)
RETURN m,n

Queries that exclusively use syntax from earlier versions of Neo4j (version 4.4 and earlier) will continue to be supported.

For example, the following will not raise a syntax error:

MATCH (m:A:B:C)-[:S|T]->()
RETURN
  CASE
    WHEN m:D:E THEN m.p
    ELSE null
  END AS result

Examples

The following graph is used for the examples below:

graph label expressions

Node pattern without label expressions

A node pattern without a label expression returns all nodes in the graph, including nodes without labels.

Example 2. Label expression
Query
MATCH (n)
RETURN n.name AS name
Table 35. Result
name

"Alice"

"Bob"

"Charlie"

"Daniel"

"Eskil"

"Frank"

"George"

"Henry"

Rows: 8

Node pattern with a single node label

A node pattern with a single label returns the nodes that contain the specified label.

Example 3. Label expression
Query
MATCH (n:A)
RETURN n.name AS name
Table 36. Result
name

"Alice"

"Daniel"

"Eskil"

"George"

Rows: 4

Node pattern with an AND expression for the node labels

A node pattern with an AND expression for the node label returns the nodes that contain both of the specified labels.

Example 4. Label expression
Query
MATCH (n:A&B)
RETURN n.name AS name
Table 37. Result
name

"Daniel"

"George"

Rows: 2

Node pattern with an OR expression for the node labels

A match with OR expressions for the node label returns the nodes that contain either of the specified labels.

Example 5. Label expression
Query
MATCH (n:A|B)
RETURN n.name AS name
Table 38. Result
name

"Alice"

"Bob"

"Daniel"

"Eskil"

"Frank"

"George"

Rows: 6

Node pattern with NOT expressions for the node labels

A node pattern with a NOT expression for the node label returns the nodes that do not contain the specified label.

Example 6. Label expression
Query
MATCH (n:!A)
RETURN n.name AS name
Table 39. Result
name

"Bob"

"Charlie"

"Frank"

"Henry"

Rows: 4

Node pattern with a Wildcard expression for the node labels

A node pattern with a Wildcard expression for the node label returns all the nodes that contain at least one label.

Example 7. Label expression
Query
MATCH (n:%)
RETURN n.name AS name
Table 40. Result
name

"Alice"

"Bob"

"Charlie"

"Daniel"

"Eskil"

"Frank"

"George"

Rows: 7

Node pattern with nested label expressions

A node pattern with nested label expressions returns the nodes for which the full expression is true.

Example 8. Label expression
Query
MATCH (n:(!A&!B)|C)
RETURN n.name AS name
Table 41. Result
name

"Charlie"

"Eskil"

"Frank"

"George"

"Henry"

Rows: 5

WHERE clause with label expressions as a predicate

A label expression can also be used as a predicate in the WHERE clause.

Example 9. Label expression
Query
MATCH (n)
WHERE n:A|B
RETURN n.name AS name
Table 42. Result
name

"Alice"

"Bob"

"Daniel"

"Eskil"

"Frank"

"George"

Rows: 6

Label expressions in the WITH and RETURN clauses

A label expression can also be used in a WITH or a RETURN clause.

Example 10. Label expression
Query
MATCH (n)
RETURN n:A&B
Table 43. Result
n:A&B

false

false

false

true

false

false

true

false

Rows: 8

Relationship type expressions

Relationship type expressions evaluate to true or false when applied to the type of a relationship.

Assuming no other filters are applied, then a relationship type expression evaluating to true means the relationship is matched.

Relationships must have exactly one type. So for example the expressions: (a)-[r:R&Q]-(b) or (a)-[r:!%]-(b) will never return any results.

Variable length relationships may only have relationship type expressions consisting of |. That means that ()-[r:!R*]-() is not allowed, whereas ()-[r:Q|R*]-() is allowed.

Relationships must have exactly one type. For example (a)-[r:R&Q]-(b) or (a)-[r:!%]-(b) will never return any results.

The following table displays whether the relationship type expression matches the relationship:

Relationship

Relationship type expression

[:A]

[:B]

[:C]

[]

[:A]

[:A&B]

[:A|B]

[:!A]

[:!!A]

[:A&!A]

[:A|!A]

[:%]

[:!%]

[:%|!%]

[:%&!%]

[:A&%]

[:A|%]

Label expressions cannot be combined with label syntax. For example, :A:B&C will throw an error. Instead, use either :A&B&C or :A:B:C.

Examples:

The following graph is used for the examples below:

graph relationship type expressions

Relationship pattern without relationship type expression

A relationship pattern without a relationship type expression returns all relationships in the graph.

Example 11. Relationship type expressions
Query
MATCH ()-[r]->()
RETURN r.name as name
Table 44. Result
name

"Teaches"

"Studies"

"Parents"

Rows: 3

Relationship pattern with a single relationship type

A relationship pattern with a single relationship type returns the relationships that contain the specified type.

Example 12. Relationship type expression
Query
MATCH ()-[r:R1]->()
RETURN r.name AS name
Table 45. Result
name

"Teaches"

Rows: 1

Relationship pattern with an OR expression for the relationship types

A relationship pattern with an OR expression for the relationship type returns all relationships that contain either of the specified types.

Example 13. Relationship type expression
Query
MATCH ()-[r:R1|R2]->()
RETURN r.name AS name
Table 46. Result
name

"Teaches"

"Studies"

Rows: 2

Relationship pattern with a NOT expression for the relationship types

A relationship pattern with a NOT expression for the relationship type returns all relationships that do not contain the specified type.

Example 14. Relationship type expression
Query
MATCH ()-[r:!R1]->()
RETURN r.name AS name
Table 47. Result
name

"Studies"

"Parents"

Rows: 2

Relationship pattern with a nested relationship type expression

A relationship pattern with a nested relationship type expression returns all relationships for which the full expression is true.

Example 15. Relationship type expression
Query
MATCH ()-[r:(!R1&!R2)|R3]->()
RETURN r.name as name
Table 48. Result
name

"Parents"

Rows: 1

WHERE clause with a relationship type expression in the predicate

A relationship type expression can also be used as a predicate in the WHERE clause.

Example 16. Relationship type expression
Query
MATCH (n)-[r]->(m)
WHERE r:R1|R2
RETURN r.name AS name
Table 49. Result
name

"Teaches"

"Studies"

Rows: 2

WITH and RETURN clauses with a relationship type expression

A relationship type expression can also be used in the WITH or RETURN clauses.

Example 17. Relationship type expression
Query
MATCH (n)-[r]->(m)
RETURN r:R1|R2 AS result
Table 50. Result
result

true

true

false

Rows: 3

CASE expression with relationship type and label expressions

A relationship type expression and a label expression can also be used in CASE expressions.

Example 18. Relationship type expression
Query
MATCH (n)-[r]->(m)
RETURN
CASE
  WHEN n:A&B THEN 1
  WHEN r:!R1&!R2 THEN 2
  ELSE -1
END AS result
Table 51. Result
result

1

-1

2

Rows: 3