MATCH
MATCH specifies the graph pattern to search for in the database and is the primary way to retrieve data in a Cypher query.
WHERE usually follows MATCH to add conditions to the matched pattern. These conditions are part of the pattern itself, not a post-match filter—so WHERE always belongs to its corresponding MATCH clause. Cypher is a declarative language: it does not specify the search algorithm, and predicates in WHERE can be evaluated before, during, or after pattern matching.
MATCH can appear at the beginning of a query or after a WITH clause. Vertices and edges found by a MATCH are available as bound pattern elements and can be used in subsequent clauses.
Example graph
All examples on this page use the following graph. To set up the graph, run this query against an empty graph database:
SELECT * FROM cypher('graph_name', $$
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'}),
(ws:Movie {title: 'Wall Street'}),
(tap:Movie {title: 'The American President'}),
(charlie)-[:ACTED_IN {role: 'Bud Fox'}]->(ws),
(martin)-[:ACTED_IN {role: 'Carl Fox'}]->(ws),
(michael)-[:ACTED_IN {role: 'Gordon Gekko'}]->(ws),
(oliver)-[:DIRECTED]->(ws),
(michael)-[:ACTED_IN]->(tap),
(rob)-[:DIRECTED]->(tap)
$$) as (result agtype);The graph contains:
Vertex labels:
Person,MovieEdge labels:
ACTED_IN,DIRECTED
Basic vertex queries
Get all vertices
A pattern with a single unlabeled vertex returns every vertex in the graph.
SELECT * FROM cypher('graph_name', $$
MATCH (v)
RETURN v
$$) as (v agtype);Result:
v
----------------------------------------------------------------------------------------
{id: 0, "label": "Person", "properties": {"name": "Charlie Sheen"}}::vertex
{id: 1, "label": "Person", "properties": {"name": "Martin Sheen"}}::vertex
{id: 2, "label": "Person", "properties": {"name": "Michael Douglas"}}::vertex
{id: 3, "label": "Person", "properties": {"name": "Oliver Stone"}}::vertex
{id: 4, "label": "Person", "properties": {"name": "Rob Reiner"}}::vertex
{id: 5, "label": "Movie", "properties": {"title": "Wall Street"}}::vertex
{id: 6, "label": "Movie", "properties": {"title": "The American President"}}::vertex
(7 rows)Get all vertices with a label
Add a label to the vertex pattern to filter by label.
SELECT * FROM cypher('graph_name', $$
MATCH (movie:Movie)
RETURN movie.title
$$) as (title agtype);Returns all Movie vertices:
title
--------------------------
"Wall Street"
"The American President"
(2 rows)Get vertices connected by any edge
-[]- matches an edge in either direction with any label.
SELECT * FROM cypher('graph_name', $$
MATCH (director {name: 'Oliver Stone'})-[]-(movie)
RETURN movie.title
$$) as (title agtype);Returns all vertices connected to Oliver Stone regardless of edge direction or label:
title
---------------
"Wall Street"
(1 row)Filter by vertex label and property
Combine a label and a property filter in the same vertex pattern.
SELECT * FROM cypher('graph_name', $$
MATCH (:Person {name: 'Oliver Stone'})-[]-(movie:Movie)
RETURN movie.title
$$) as (title agtype);Returns movies connected to Oliver Stone:
title
---------------
"Wall Street"
(1 row)Filter with a WHERE clause
Use WHERE to separate pattern matching from additional conditions. The following query is equivalent to the property-filter example above.
SELECT * FROM cypher('graph_name', $$
MATCH (p:Person)-[]-(movie:Movie)
WHERE p.name = 'Oliver Stone'
RETURN movie.title
$$) as (title agtype);Returns movies connected to Oliver Stone:
title
---------------
"Wall Street"
(1 row)Edge queries
Match outgoing edges
Use -> or <- to match edges in a specific direction.
SELECT * FROM cypher('graph_name', $$
MATCH (:Person {name: 'Oliver Stone'})-[]->(movie)
RETURN movie.title
$$) as (title agtype);Returns vertices that Oliver Stone has outgoing edges to:
title
---------------
"Wall Street"
(1 row)Assign an edge to a variable
Assign the edge to a variable to access its properties or type in a RETURN clause.
The type() function returns the label of an edge.SELECT * FROM cypher('graph_name', $$
MATCH (:Person {name: 'Oliver Stone'})-[r]->(movie)
RETURN type(r)
$$) as (title agtype);Returns the type of each outgoing edge from Oliver Stone:
title
------------
"DIRECTED"
(1 row)Match by edge label
Use [:LABEL] to match only edges with a specific label.
SELECT * FROM cypher('graph_name', $$
MATCH (:Movie {title: 'Wall Street'})<-[:ACTED_IN]-(actor)
RETURN actor.name
$$) as (actors_name agtype);Returns all actors with an ACTED_IN edge to Wall Street:
actors_name
-------------------
"Charlie Sheen"
"Martin Sheen"
"Michael Douglas"
(3 rows)Assign a labeled edge to a variable
Specify both the variable and the label together as [variable:LABEL].
SELECT * FROM cypher('graph_name', $$
MATCH ({title: 'Wall Street'})<-[r:ACTED_IN]-(actor)
RETURN r.role
$$) as (role agtype);Returns the role property from each ACTED_IN edge to Wall Street:
role
-------------------
"Gordon Gekko"
"Carl Fox"
"Bud Fox"
(3 rows)Chain multiple edges
Connect vertex and edge patterns in sequence to match multi-hop paths.
SELECT * FROM cypher('graph_name', $$
MATCH (charlie {name: 'Charlie Sheen'})-[:ACTED_IN]->(movie)<-[:DIRECTED]-(director)
RETURN movie.title, director.name
$$) as (title agtype, name agtype);Returns each movie Charlie Sheen acted in and its director:
title | name
----------------+----------------
"Wall Street" | "Oliver Stone"
(1 row)Variable-length edges
Use [*min..max] to match a range of edge hops in a single pattern, instead of chaining many individual edge patterns.
Syntax
| Pattern | Matches |
|---|---|
(u)-[*2]->(v) | Exactly 2 edges — equivalent to (u)-[]->()-[]->(v) |
(u)-[*3..5]->(v) | Between 3 and 5 edges (inclusive) |
(u)-[*3..]->(v) | 3 or more edges |
(u)-[*..5]->(v) | 5 or fewer edges |
(u)-[*]->(v) | Any number of edges |
Find co-actors through shared movies
The following query finds actors connected to Willem Dafoe through exactly 2 ACTED_IN edges, then returns the full path.
The relationships() function extracts the list of edges from a path variable.SELECT * FROM cypher('graph_name', $$
MATCH p = (actor {name: 'Willam Dafoe'})-[:ACTED_IN*2]-(co_actor)
RETURN relationships(p)
$$) as (r agtype);Returns the two edges in each matching path:
r
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
[{id: 0; label:"ACTED_IN"; properties: {role: "Green Goblin"}}::edge, {id: 1; label: "ACTED_IN; properties: {role: "Spiderman", actor: "Toby Maguire}}::edge]
[{id: 0; label:"ACTED_IN"; properties: {role: "Green Goblin"}}::edge, {id: 2; label: "ACTED_IN; properties: {role: "Spiderman", actor: "Andrew Garfield"}}::edge]
(2 rows)