Path pattern expressions
Similar to existential subqueries, path pattern expressions can be used to assert whether a specified path exists at least once in a graph. While existential subqueries are more powerful and capable of performing anything achievable with path pattern expressions, path pattern expressions are more concise.
For more information about graph pattern matching in Cypher®, see Patterns.
Rules
Path pattern expressions have the following restrictions (use cases that require extended functionality should consider using existential subqueries instead):
-
Path pattern expressions may only use a subset of graph pattern semantics.
-
A path pattern expression must be a path pattern of length greater than zero. In other words, it must contain at least one relationship or variable-length relationship.
-
Path pattern expressions may not declare new variables. They can only reference existing variables.
-
Path pattern expressions may only be used in positions where a boolean expression is expected. The following sections will demonstrate how to use path pattern expressions in a
WHERE
clause.
Example graph
The following graph is used for the examples below:
To recreate the graph, run the following query in an empty Neo4j database:
CREATE (alice:Person {name:'Alice', age: 65, role: 'Project manager'}),
(cecil:Person {name: 'Cecil', age: 25, role: 'Software developer'}),
(cecilia:Person {name: 'Cecilia', age: 31, role: 'Software developer'}),
(cecil)-[:WORKS_FOR {since: 2023}]->(alice),
(cecilia)-[:WORKS_FOR {since: 2015}]->(alice)
Examples
MATCH (employee:Person)
WHERE (employee)-[:WORKS_FOR]->(:Person {name: 'Alice'})
RETURN employee.name AS employee
employee |
---|
|
|
Rows: 2 |
NOT
and AND
MATCH (employee:Person)
WHERE NOT employee.name = 'Cecil' AND (employee)-[:WORKS_FOR]->(:Person {name: 'Alice'})
RETURN employee.name AS employee
employee |
---|
|
Rows: 1 |
For more information about Cypher’s boolean operators, see Predicate expressions → Boolean operators.
Patterns can be placed inside expressions.
RETURN NOT (:Person {name: "Alice"})<-[:WORKS_FOR {since: 2023}]-(:Person) AS patternCheck
patternCheck |
---|
|
Rows: 1 |
NOT is required in the above example to make the query a valid predicate expression. Without it, the query would be invalid because the expression would not return a BOOLEAN value.
|
The exists()
function can be used to check for the presence of a pattern.
Note that this function not as versatile as the EXISTS
subqueries.
exists()
function to check if a pattern existsRETURN exists((:Person)-[:WORKS_FOR {since: 2023}]->(:Person {name: "Alice"})) AS patternCheck
patternCheck |
---|
|
Rows: 1 |