Label expression predicates

You can use a label expression predicate to verify that the labels of a node or the relationship type of a relationship match a given label expression.

Syntax

<expr>:<label-expression>

Where <expr> is any Cypher® expression and <label-expression> is any Cypher label expression.

Example graph

The following graph is used for the examples on this page:

label expression predicates graph

To recreate the graph, run the following query against an empty Neo4j database:

CREATE (alice:Person&Manager {name:'Alice', age: 65, skills: ['Java', 'Python']}),
       (cecil:Person&Developer {name: 'Cecil', age: 25, skills: ['Java', 'Python']}),
       (cecilia:Person&Developer {name: 'Cecilia', age: 31, skills: ['JavaScript', 'TypeScript']}),
       (charlie:Person&Engineer {name: 'Charlie', age: 61, skills: ['C++', 'Python']}),
       (daniel:Person&Director {name: 'Daniel', age: 39, skills: ['JavaScript', 'Slides']}),
       (eskil:Person&CEO {name: 'Eskil', age: 39, skills: ['Slides', 'ChatGPT']}),

       (cecil)-[:WORKS_FOR]->(alice),
       (cecilia)-[:WORKS_FOR]->(alice),
       (charlie)-[:WORKS_FOR]->(daniel),
       (alice)-[:REPORTS_TO]->(daniel),
       (daniel)-[:REPORTS_TO]->(eskil)

Test whether a node has a certain label

Given that p is a node, p:Manager tests whether p has the label Manager or not and results in true or false, respectively.

MATCH (p:Person)
RETURN p.name AS name, p:Manager AS isManager
name isManager

"Alice"

true

"Cecil"

false

"Cecilia"

false

"Charlie"

false

"Daniel"

false

"Eskil"

false

Rows: 6

Given that p is a node and a more complex label expression, e.g, Manager|Director|CEO, p:Manager|Director|CEO tests whether node p matches the label expression Manager|Director|CEO or not and results in true or false, respectively. More specifically, p:Manager|Director|CEO tests whether p has at least one of the three labels Manager, Director, and CEO.

MATCH (p:Person)
RETURN p.name AS name,
       p:Manager|Director|CEO AS isManager
name isManager

"Alice"

true

"Cecil"

false

"Cecilia"

false

"Charlie"

false

"Daniel"

true

"Eskil"

true

Rows: 6

p:!CEO tests whether p does not have the label CEO.

MATCH (p:Person)-[r]->(m)
RETURN p.name AS name,
       m:!CEO AS doesNotWorkDirectlyForTheCEO
name doesNotWorkDirectlyForTheCEO

"Alice"

true

"Cecil"

true

"Cecilia"

true

"Charlie"

true

"Daniel"

false

Rows: 5

When <exp> results in ´null`, then the label expression predicate results in null, e.g. if p is null, then p:!CEO results in null.

MATCH (p:Person)
OPTIONAL MATCH (p)-[r]->(m)
RETURN p.name AS name,
       m:!CEO AS doesNotWorkDirectlyForTheCEO
name doesNotWorkDirectlyForTheCEO

"Alice"

true

"Cecil"

true

"Cecilia"

true

"Charlie"

true

"Daniel"

false

"Eskil"

null

Rows: 6

The function coalesce allows to turn null into a default value:

MATCH (p:Person)
OPTIONAL MATCH (p)-[r]->(m)
RETURN p.name AS name,
       coalesce(m:!CEO, false) AS doesNotWorkDirectlyForTheCEO
name doesNotWorkDirectlyForTheCEO

"Alice"

true

"Cecil"

true

"Cecilia"

true

"Charlie"

true

"Daniel"

false

"Eskil"

false

Rows: 6

Test whether a node matches a dynamic label expression

If you don’t know the manager labels, you can infer a list of managerLabels by collecting all non-Person labels from people with a direct report. You can test nodes with the label expression predicate to match a dynamic label expression. p:$any(managerLabels) tests whether a node p has at least on of the label in the list managerLabels.

MATCH ()-[r]->(p:Person)
UNWIND labels(p) AS label
FILTER label <> "Person"
RETURN COLLECT(label) AS managerLabels
NEXT
MATCH (p)
RETURN p.name AS name, p:$any(managerLabels) AS isManager
name isManager

"Alice"

true

"Cecil"

false

"Cecilia"

false

"Charlie"

false

"Daniel"

true

"Eskil"

true

Rows: 6

Test whether a relationship has a certain relationship type

Given that r is a relationship, r:WORKS_FOR tests whether r has the relationship type WORKS_FOR or not and result in true or false, respectively.

MATCH (p:Person)-[r]->()
RETURN p.name AS name,
       r:WORKS_FOR AS isNotManager
name isNotManager

"Alice"

false

"Cecil"

true

"Cecilia"

true

"Charlie"

true

"Daniel"

false

Rows: 5

If r is null, then the label expression predicate, e.g. r:WORKS_FOR|REPORTS_TO, results in null. The function coalesce allows to turn null into a default value.

MATCH (p:Person)
OPTIONAL MATCH ()-[r]->(p)
RETURN DISTINCT
  p.name AS name,
  coalesce(r:WORKS_FOR|REPORTS_TO, false) AS hasReports
name hasReports

"Alice"

true

"Cecil"

false

"Cecilia"

false

"Charlie"

false

"Daniel"

true

"Eskil"

true

Rows: 6