MATCH

The MATCH clause lets you specify a pattern that Cypher will search for in the graph. It is the primary mechanism for retrieving data to use in a query.

A WHERE clause is commonly used after MATCH to add user-defined constraints to the matched pattern, thereby refining the result set. Predicates are part of the pattern description and should not be interpreted as filters applied only after matching completes. Therefore, WHERE must always appear adjacent to its corresponding MATCH clause.

MATCH may appear at the beginning of a query or later — for example, after a WITH clause. If it is the first clause, no variables are yet bound; Cypher will plan a search to find results matching the pattern and any associated WHERE predicates. Vertices and edges found by this search become bound pattern elements and may be used for subsequent subgraph pattern matching. They may also be referenced in later clauses, where Cypher uses known elements to discover additional unknown ones.

Cypher is a declarative language: queries typically do not specify the exact algorithm used to perform pattern matching. Predicates in WHERE may be evaluated before, during, or after pattern matching.

Basic Vertex Matching

Retrieve All Vertices

To return all vertices in the graph, specify a pattern containing a single unlabeled vertex.

Query

SELECT * FROM cypher('graph_name', $$
MATCH (v)
RETURN v
$$) 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 rows returned

Retrieve All Vertices with a Specific Label

To retrieve all vertices bearing a specific label, include the label in the vertex pattern.

Query

SELECT * FROM cypher('graph_name', $$
MATCH (movie:Movie)
RETURN movie.title
$$) AS (title agtype);

Returns all movies in the database.

title
'Wall Street'
'The American President'
2 rows returned

Match Connected Vertices

The syntax -[]- specifies an undirected edge, without constraining type or direction.

Query

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

Returns all movies connected to the Person vertex named 'Oliver Stone'.

title
'Wall Street'
1 row returned

Labeled Vertex Matching

To constrain a vertex to a specific label within a pattern, append the label using colon syntax.

Query

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

Returns all Movie vertices connected to the Person vertex named 'Oliver Stone'.

title
'Wall Street'
1 row returned

Basic Edge Operations

Undirected Edges

Use - to match undirected edges.

Query

SELECT * FROM cypher('graph_name', $$
MATCH (:Person {name: 'Oliver Stone'})-[]-(movie)
RETURN movie
$$) AS (title agtype);

Returns all vertices connected to the Person 'Oliver Stone'.

title
'Wall Street'
1 row returned

Outgoing Edges

Use -> or <- to specify edge direction.

Query

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

Returns all vertices reachable from 'Oliver Stone' via outgoing edges.

title
'Wall Street'
1 row returned

Directed Edges with Variables

To reference an edge — for filtering on its properties or returning it — assign it to a variable in the pattern.

Query

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 returned

Matching by Edge Label

When the edge label is known, specify it explicitly using :Label.

Query

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

Returns all actors who ACTED_IN 'Wall Street'.

actors_name
'Charlie Sheen'
'Martin Sheen'
'Michael Douglas'
3 rows returned

Edge Label Matching with Variables

To both bind an edge to a variable and constrain its label, specify both in the pattern.

Query

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

Returns the role property of each ACTED_IN edge incident to 'Wall Street'.

role
'Gordon Gekko'
'Carl Fox'
'Bud Fox'
3 rows returned

Chaining Multiple Edges

Edges may be chained to match arbitrarily long paths. As long as the basic pattern ()-[]-() is respected, users may combine vertices and edges to express complex structural patterns.

Query

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 movies starring 'Charlie Sheen' and their directors.

title name
'Wall Street' 'Oliver Stone'
1 row returned

Variable-Length Relationships (Limited Support)

When the number of relationships between two vertices is unknown or variable, use variable-length syntax to match sequences of edges (and intermediate vertices).

Note!
In YMatrix AGE:

  • Only (u)-[*]-(v) is supported. Other forms — such as (u)-[*]-(v)-[]-() or (u)-[*]->(v)-[*]-() — raise the error:
    ERROR: variable-length relationships in paths are only supported for paths of length 3.
  • Variable-length patterns cannot reference pre-bound variables. For example, MATCH (u) MATCH (u)-[*]-(v) raises:
    ERROR: VLE paths cannot reference existing variables.
  • The SQL-level age_vle() function is unavailable in YMatrix AGE. Variable-length path matching is supported only via Cypher VLE syntax (e.g., (u)-[*1..3]->(v)).

Introduction

Instead of spelling out long paths using repeated vertex-edge patterns, you can describe multiple relationships (and intervening vertices) by specifying length directly in the edge portion of the pattern.

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

Describes a right-directed path of three vertices and two edges, equivalent to:

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

You may also specify a range:

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

Is equivalent to matching all of the following:

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

The above examples define lower and upper bounds on the number of relationships (and intermediate vertices) between u and v. Either bound may be omitted.

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

Returns all paths between u and v containing three or more relationships.

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

Returns all paths between u and v containing five or fewer relationships.

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

Returns all paths between u and v.

Example

Query

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

Returns lists of edges representing 'Willam Dafoe'’s ACTED_IN relationships and those of two co-stars who played Spider-Man.

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 returned