MATCH
Introduction
The MATCH
clause allows you to specify the patterns Neo4j will search for in the database.
This is the primary way of getting data into the current set of bindings.
For more information about how MATCH
is used to find patterns (including quantified path patterns, quantified relationships, and shortest path), see the section on Patterns.
MATCH
is often coupled to a WHERE
part which adds restrictions, or predicates, to the MATCH
patterns, making them more specific.
The predicates are part of the pattern description, and should not be considered a filter applied only after the matching is done.
This means that WHERE
should always be put together with the MATCH
clause it belongs to.
MATCH
can occur at the beginning of the query or later, possibly after a WITH
.
If it is the first clause, nothing will have been bound yet, and Neo4j will design a search to find the results matching the clause and any associated predicates specified in any WHERE
part.
This could involve a scan of the database, a search for nodes having a certain label, or a search of an index to find starting points for the pattern matching.
Nodes and relationships found by this search are available as bound pattern elements, and can be used for pattern matching of paths.
They can also be used in any further MATCH
clauses, where Neo4j will use the known elements, and from there find further unknown elements.
Cypher® is declarative, and so usually the query itself does not specify the algorithm to use to perform the search.
Neo4j will automatically work out the best approach to finding start nodes and matching patterns.
Predicates in WHERE
parts can be evaluated before pattern matching, during pattern matching, or after finding matches.
However, there are cases where you can influence the decisions taken by the query compiler.
Read more about indexes in Indexes for search performance, and more about specifying hints to force Neo4j to solve a query in a specific way in Planner hints and the USING keyword.
Example graph
The following graph is used for the examples below:
To recreate the graph, run the following query against an empty Neo4j database:
CREATE
(charlie:Person {name: 'Charlie Sheen'}),
(martin:Person {name: 'Martin Sheen'}),
(michael:Person {name: 'Michael Douglas'}),
(oliver:Person {name: 'Oliver Stone'}),
(rob:Person {name: 'Rob Reiner'}),
(wallStreet:Movie {title: 'Wall Street'}),
(charlie)-[:ACTED_IN {role: 'Bud Fox'}]->(wallStreet),
(martin)-[:ACTED_IN {role: 'Carl Fox'}]->(wallStreet),
(michael)-[:ACTED_IN {role: 'Gordon Gekko'}]->(wallStreet),
(oliver)-[:DIRECTED]->(wallStreet),
(thePresident:Movie {title: 'The American President'}),
(martin)-[:ACTED_IN {role: 'A.J. MacInerney'}]->(thePresident),
(michael)-[:ACTED_IN {role: 'President Andrew Shepherd'}]->(thePresident),
(rob)-[:DIRECTED]->(thePresident),
(martin)-[:FATHER_OF]->(charlie)
Basic node finding
Get all nodes
By specifying a pattern with a single node and no labels, all nodes in the graph will be returned.
MATCH (n)
RETURN n
Returns all the nodes in the database.
n |
---|
|
|
|
|
|
|
|
|
Get all nodes with a label
Find all nodes with a specific label:
MATCH (movie:Movie)
RETURN movie.title
Returns all the nodes with the Movie
label in the database.
movie.title |
---|
|
|
|
Related nodes
The symbol --
means related to, without regard to type or direction of the relationship.
MATCH (director {name: 'Oliver Stone'})--(movie)
RETURN movie.title
Returns all the movies directed by Oliver Stone
.
movie.title |
---|
|
|
Match with labels
To constrain a pattern with labels on nodes, add the labels to the nodes in the pattern.
MATCH (:Person {name: 'Oliver Stone'})--(movie:Movie)
RETURN movie.title
Returns any nodes with the Movie
label connected to Oliver Stone
.
movie.title |
---|
|
|
Match with a label expression for the node labels
A match with an OR
expression for the node label returns the nodes that contains both the specified labels.
MATCH (n:Movie|Person)
RETURN n.name AS name, n.title AS title
name | title |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Relationship basics
Outgoing relationships
When the direction of a relationship is of interest, it is shown by using -→
or ←-
.
For example:
MATCH (:Person {name: 'Oliver Stone'})-->(movie)
RETURN movie.title
Returns any nodes connected by an outgoing relationship to the Person
node with the name
property set to Oliver Stone
.
movie.title |
---|
|
|
Relationship variables
It is possible to introduce a variable to a pattern, either for filtering on relationship properties or to return a relationship. For example:
MATCH (:Person {name: 'Oliver Stone'})-[r]->(movie)
RETURN type(r)
Returns the type of each outgoing relationship from Oliver Stone
.
type(r) |
---|
|
|
Match on an undirected relationship
When a pattern contains a bound relationship, and that relationship pattern does not specify direction, Cypher will try to match the relationship in both directions.
MATCH (a)-[:ACTED_IN {role: 'Bud Fox'}]-(b)
RETURN a, b
a | b |
---|---|
|
|
|
|
|
Match on relationship type
When the relationship type to match on is known, it is possible to specify it by using a colon (:
) before the relationship type.
MATCH (wallstreet:Movie {title: 'Wall Street'})<-[:ACTED_IN]-(actor)
RETURN actor.name
Returns all actors who ACTED_IN
the movie Wall Street
.
actor.name |
---|
|
|
|
|
Read more about relationship type expressions.
Match on multiple relationship types
It is possible to match on multiple relationship types by using the pipe symbol (|
).
For example:
MATCH (wallstreet {title: 'Wall Street'})<-[:ACTED_IN|DIRECTED]-(person)
RETURN person.name
Returns nodes with an ACTED_IN
or DIRECTED
relationship to the movie Wall Street
.
person.name |
---|
|
|
|
|
|
Match on relationship type and use a variable
Variables and specific relationship types can be included in the same pattern. For example:
MATCH (wallstreet {title: 'Wall Street'})<-[r:ACTED_IN]-(actor)
RETURN r.role
Returns the ACTED_IN
roles for the movie Wall Street
.
r.role |
---|
|
|
|
|
Relationships in depth
Relationships will only be matched once inside a single pattern. Read more about this in the section on relationship uniqueness. |
Relationship types with uncommon characters
Databases occasionally contain relationship types including non-alphanumerical characters, or with spaces in them.
These are created using backticks (`
).
For example, the following query creates a relationship which contains a space (OLD FRIENDS
) between Martin Sheen
and Rob Reiner
.
MATCH
(martin:Person {name: 'Martin Sheen'}),
(rob:Person {name: 'Rob Reiner'})
CREATE (rob)-[:`OLD FRIENDS`]->(martin)
This leads to the following graph:
MATCH (n {name: 'Rob Reiner'})-[r:`OLD FRIENDS`]->()
RETURN type(r)
type(r) |
---|
|
|
Multiple relationships
Relationships can be expressed by using multiple statements in the form of ()--()
, or they can be strung together.
For example:
MATCH (charlie {name: 'Charlie Sheen'})-[:ACTED_IN]->(movie)<-[:DIRECTED]-(director)
RETURN movie.title, director.name
Returns the movie in which Charlie Sheen
acted and its director.
movie.title | director.name |
---|---|
|
|
|
Was this page helpful?