The MATCH clause allows you to specify the patterns a query will search for in the database. This is the primary way of retrieving data for use in a query.

A WHERE clause often follows a MATCH clause to add user-defined restrictions to the matched patterns to manipulate the set of data returned. 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 Cypher will design a search to find the results matching the clause and any associated predicates specified in any WHERE clause. Vertices and edges found by this search are available as bound pattern elements, and can be used for pattern matching of sub-graphs. They can also be used in any future clauses, where Cypher will use the known elements, and from there find further unknown elements.

Cypher is a declarative language, and so typically the query itself does not specify the algorithm to use to perform the search. Predicates in WHERE parts can be evaluated before pattern matching, during pattern matching, or after the match is found.

Basic vertex finding

Get all Vertices

By specifying a pattern with a single vertex and no labels, all vertices in the graph will be returned.

Query

  1. SELECT * FROM cypher('graph_name', $$
  2. MATCH (v)
  3. RETURN v
  4. $$) as (v agtype);

Returns all vertices in the database.

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: {name: ‘Wall Street’}}::vertex
{id: 6; label: ‘Movie’; properties: {title: ‘The American President’}}::vertex
7 row(s) returned

Get all vertices with a label

Getting all vertices with a label is done with a single node pattern where the vertex has the label specified as follows:

Query

  1. SELECT * FROM cypher('graph_name', $$
  2. MATCH (movie:Movie)
  3. RETURN movie.title
  4. $$) as (title agtype);

Returns all the movies in the database.

title
‘Wall Street’
‘The American President’
2 row(s) returned

The symbol -[]- specifies an edge, without specifying the type or direction of the edge.

Query

  1. SELECT * FROM cypher('graph_name', $$
  2. MATCH (director {name: 'Oliver Stone'})-[]-(movie)
  3. RETURN movie.title
  4. $$) as (title agtype);

Returns all the movies directed by ‘Oliver Stone’.

title
‘Wall Street’
1 row(s) returned

Match with labels

To constrain your pattern with labels on vertices, add it to the vertex in the pattern, using the label syntax.

Query

  1. SELECT * FROM cypher('graph_name', $$
  2. MATCH (:Person {name: 'Oliver Stone'})-[]-(movie:Movie)
  3. RETURN movie.title
  4. $$) as (title agtype);

Returns any vertices connected with the Person ‘Oliver’ that are labeled Movie.

title
‘Wall Street’
1 row(s) returned

Edge basics

Outgoing Edges

To return directed edges, you may use -> or <- to specify the direction of which the edge points.

Query

  1. SELECT * FROM cypher('graph_name', $$
  2. MATCH (:Person {name: 'Oliver Stone'})-[]->(movie)
  3. RETURN movie.title
  4. $$) as (title agtype);

Returns any vertices connected with the Person ‘Oliver’ by an outgoing edge.

title
‘Wall Street’
1 row(s) returned

Directed Edges and variable

If a variable is required, either for filtering on properties of the edge, or to return the edge, specify the variable within the edge or vertex you wish to use.

Query

  1. SELECT * FROM cypher('graph_name', $$
  2. MATCH (:Person {name: 'Oliver Stone'})-[r]->(movie)
  3. RETURN type(r)
  4. $$) as (title agtype);

Returns the type of each outgoing edge from ‘Oliver’.

title
‘DIRECTED’
1 row(s) returned

Match on edge label

When you know the edge label you want to match on, you can specify it by using a colon together with the edge label.

Query

  1. SELECT * FROM cypher('graph_name', $$
  2. MATCH (:Movie {title: 'Wall Street'})<-[:ACTED_IN]-(actor)
  3. RETURN actor.name
  4. $$) as (actors_name agtype);

Returns all actors that ACTED_IN ‘Wall Street’.

actors_name
‘Charlie Sheen’
‘Martin Sheen’
‘Michael Douglas’
3 row(s) returned

Match on edge label with a variable

If you want to use a variable to hold the edge, and specify the edge label you want, you can do so by specifying them both.

Query

  1. SELECT * FROM cypher('graph_name', $$
  2. MATCH ({title: 'Wall Street'})<-[r:ACTED_IN]-(actor)
  3. RETURN r.role
  4. $$) as (role agtype);

Returns ACTED_IN roles for ‘Wall Street’.

role
‘Gordon Gekko’
‘Carl Fox’
‘Bud Fox’
3 row(s) returned

Multiple Edges

Edges can be strung together to match an infinite number of edges. As long as the base pattern ()-[]-() is followed, users can chain together edges and vertices to match specific patterns.

Query

  1. SELECT * FROM cypher('graph_name', $$
  2. MATCH (charlie {name: 'Charlie Sheen'})-[:ACTED_IN]->(movie)<-[:DIRECTED]-(director)
  3. RETURN movie.title, director.name
  4. $$) as (title agtype, name agtype);

Returns the movie ‘Charlie Sheen’ acted in and its director.

title name
‘Wall Street’ ‘Oliver Stone’
1 row(s) returned

Variable Length Edges

When the connection between two vertices is of variable length, the list of edges that form the connection can be returned using the following connection.

Introduction

Rather than describing a long path using a sequence of many vertex and edge descriptions in a pattern, many edges (and the intermediate vertices) can be described by specifying a length in the edge description of a pattern.

  1. (u)-[*2]->(v)

Which describes a right directed path of three vertices and two edges can be rewritten to:

  1. (u)-[]->()-[]->(v)

A range length can also be given:

  1. (u)-[*3..5]->(v)

Which is equivalent to:

  1. (u)-[]->()-[]->()-[]->(v) and
  2. (u)-[]->()-[]->()-[]->()-[]->(v) and
  3. (u)-[]->()-[]->()-[]->()-[]->()-[]->(v)

The previous example provided gave the edge both an lower and upper bound for the number of edges (and vertices) between u and v. Either one or both of these binding values can be excluded.

  1. (u)-[*3..]->(v)

Returns all paths between u and v that have three or more edges included.

  1. (u)-[*..5]->(v)

Returns all paths between u and v that have 5 or fewer edges included.

  1. (u)-[*]->(v)

Returns all paths between u and v.

Example

Query

  1. SELECT * FROM cypher('graph_name', $$
  2. MATCH p = (actor {name: 'Willam Dafoe'})-[:ACTED_IN*2]-(co_actor)
  3. RETURN relationships(p)
  4. $$) as (r agtype);

Returns the list of edges, including the one that Willam Dafoe acted in and the two Spiderman actors he worked with.

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 row(s) returned