MATCH

Updated at:

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, Movie

  • Edge 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

PatternMatches
(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)