Overview
The MATCH
statement allows you to specify graph patterns to search for in the graph. It is the fundamental statement for retrieving data from the graph database and binding them to variables for use in subsequent parts of the query.
<match statement> ::=
[ "OPTIONAL" ] "MATCH" <graph pattern> [ <graph pattern yield clause> ]
<graph pattern yield clause> ::=
"YIELD" <graph pattern yield item> [ { "," <graph pattern yield item> }... ]
<graph pattern yield item> ::=
<node variable reference> | <edge variable reference> | <path variable reference>
Details
- You can use the label expression, property specification, and WHERE clause to apply search conditions to the
<graph pattern>
. - You can use the keyword
OPTIONAL
withMATCH
. See OPTIONAL MATCH. - The
MATCH
statement supports theYIELD
clause. See MATCH YIELD.
Example Graph

CREATE GRAPH myGraph {
NODE User ({name string}),
NODE Club ({since uint32}),
EDGE Follows ()-[{createdOn datetime}]->(),
EDGE Joins ()-[{memberNo uint32}]->()
} PARTITION BY HASH(Crc32) SHARDS [1]
INSERT (rowlock:User {_id: 'U01', name: 'rowlock'}),
(brainy:User {_id: 'U02', name: 'Brainy'}),
(purplechalk:User {_id: 'U03', name: 'purplechalk'}),
(mochaeach:User {_id: 'U04', name: 'mochaeach'}),
(lionbower:User {_id: 'U05', name: 'lionbower'}),
(c01:Club {_id: 'C01', since: 2005}),
(c02:Club {_id: 'C02', since: 2005}),
(rowlock)-[:Follows {createdOn: '2024-1-5'}]->(brainy),
(mochaeach)-[:Follows {createdOn: '2024-2-10'}]->(brainy),
(brainy)-[:Follows {createdOn: '2024-2-1'}]->(purplechalk),
(purplechalk)-[:Follows {createdOn: '2024-5-3'}]->(lionbower),
(brainy)-[:Joins {memberNo: 1}]->(c01),
(lionbower)-[:Joins {memberNo: 2}]->(c01),
(mochaeach)-[:Joins {memberNo: 9}]->(c02)
Matching All Nodes
To match all nodes, use a node pattern without the label and property filtering.
MATCH (n)
RETURN n
Result: n
_id | _uuid | schema | values |
---|---|---|---|
U05 | Sys-gen | User | {name: "lionbower"} |
U04 | Sys-gen | User | {name: "mochaeach"} |
U03 | Sys-gen | User | {name: "purplechalk"} |
U02 | Sys-gen | User | {name: "Brainy"} |
U01 | Sys-gen | User | {name: "rowlock"} |
C02 | Sys-gen | Club | {since: 2005} |
C01 | Sys-gen | Club | {since: 2005} |
Matching All Edges
To match all edges, use an edge pattern without the label and property filtering.
MATCH ()-[e]->()
RETURN e
Result: e
_uuid |
_from |
_to |
_from_uuid |
_to_uuid |
schema |
values |
---|---|---|---|---|---|---|
Sys-gen | U01 | U02 | UUID of U01 | UUID of U02 | Follows | {createdOn: "2024-01-05 00:00:00" } |
Sys-gen | U02 | U03 | UUID of U02 | UUID of U03 | Follows | {createdOn: "2024-02-01 00:00:00"} |
Sys-gen | U03 | U05 | UUID of U03 | UUID of U05 | Follows | {createdOn: "2024-05-03 00:00:00"} |
Sys-gen | U04 | U02 | UUID of U04 | UUID of U02 | Follows | {createdOn: "2024-02-10 00:00:00"} |
Sys-gen | U02 | C01 | UUID of U02 | UUID of C01 | Joins | {memberNo: 1} |
Sys-gen | U05 | C01 | UUID of U05 | UUID of C01 | Joins | {memberNo: 2} |
Sys-gen | U04 | C02 | UUID of U04 | UUID of C02 | Joins | {memberNo: 9} |
Notice that if you don't specifiy the edge direction, either as outgoing (>
) or incoming (<
), each edge in the graph will be returned twice, as two paths are considered distinct when their element sequences differ, i.e., (n1)-[e]->(n2)
and (n2)<-[e]-(n1)
are different paths.
MATCH ()-[e]-()
RETURN e
Matching with Labels
Both node pattern and edge pattern support the label expression to specify one or multiple labels.
To retrieve all Club
nodes:
MATCH (n:Club)
RETURN n
Result: n
_id | _uuid | schema | values |
---|---|---|---|
C02 | Sys-gen | Club | {since: 2005} |
C01 | Sys-gen | Club | {since: 2005} |
To retrieve all nodes connected to Brainy
with Follows
or Joins
edges:
MATCH (:User {name: 'Brainy'})-[:Follows|Joins]-(n)
RETURN n
Result: n
_id | _uuid | schema | values |
---|---|---|---|
U03 | Sys-gen | User | {name: "purplechalk"} |
C01 | Sys-gen | Club | {since: 2005} |
Matching with Property Specification
Property specification can be included in node and edge patterns to apply joint equalities to filter nodes and edges with key-value pairs.
To retrieve Club
nodes whose _id
and since
have specific values:
MATCH (n:Club {_id: 'C01', since: 2005})
RETURN n
Result: n
_id | _uuid | schema | values |
---|---|---|---|
C01 | Sys-gen | Club | {since: 2005} |
To retrieve the member of club C01
whose memberNo
is 1:
MATCH (:Club {_id: 'C01'})<-[:Joins {memberNo: 1}]-(n)
RETURN n
Result: n
_id | _uuid | schema | values |
---|---|---|---|
U02 | Sys-gen | User | {name: "Brainy"} |
Matching with Abbreviated Edges
When edge labels and properties are not relevant, and variables are not needed for later reference, you can simplify by using abbreviated edge patterns. The direction of the edges can still be specified if required.
To retrieve nodes connected with mochaeach
with any outgoing edges:
MATCH (:User {name: 'mochaeach'})->(n)
RETURN n
Result: n
_id | _uuid | schema | values |
---|---|---|---|
U02 | Sys-gen | User | {name: "Brainy"} |
C02 | Sys-gen | Club | {since: 2005} |
Matching Paths
To retrieve users followed by mochaeach
, and the clubs joined by those users:
MATCH p = (:User {name: 'mochaeach'})-[:Follows]->(:User)-[:Joins]->(:Club)
RETURN p
Result: p

Matching with WHERE Clauses
The WHERE
clause can be used within an element pattern (node or edge pattern), a parenthesized path pattern, or immediately after a graph pattern in the MATCH
statement to specify various search conditions.
Element Pattern WHERE Clause
To retrieve 1-step paths with outgoing Follows
edges, where their createdOn
values are greater than a specified date:
MATCH p = ()-[e:Follows WHERE e.createdOn > '2024-4-1']->()
RETURN p
Result: p

Parenthesized Path Pattern WHERE Clause
To retrieve one- or two-step paths containing outgoing Follows
edges, where their createdOn
values are smaller than a specified value:
MATCH p = (()-[e:Follows]->() WHERE e.createdOn < "2024-2-5"){1,2}
RETURN p
Result: p

Graph Pattern WHERE Clause
To retrieve members of club C01
whose memberNo
is greater than 1:
MATCH (c:Club)<-[e:Joins]->(n)
WHERE c._id = 'C01' AND e.memberNo > 1
RETURN n
Result: n
_id | _uuid | schema | values |
---|---|---|---|
U05 | Sys-gen | User | {name: "lionbower"} |
Matching Quantified Paths
A quantified path pattern constructs a path in which either the entire path or a segment of it repeats a specified number of times.
Using Quantified Edges
To retrieve distinct nodes related to lionbower
in 1 to 3 hops:
MATCH (:User {name: 'lionbower'})-[]-{1,3}(n)
RETURN collect_list(DISTINCT n._id) AS IDs
Result:
IDs |
---|
["C01","U01","U02","U03","U04"] |
Using Quantified Paths
To retrieve paths that begin with one- or two-step subpaths containing Follows
edges, where their createdOn
values are greater than a specified value, and these subpaths must connect to node C01
:
MATCH p = (()-[e:Follows]->() WHERE e.createdOn > "2024-1-31"){1,2}()-({_id:"C01"})
RETURN p
Result: p

Matching Shortest Paths
A shortest paths between two nodes are the paths that has the fewest edges.
To retrieve all the shortest paths between lionbower
and purplechalk
within 5 hops:
MATCH p = ALL SHORTEST (n1:User)-[]-{,5}(n2:User)
WHERE n1.name = 'lionbower' AND n2.name = 'purplechalk'
RETURN p
Result: p

Matching Connected Paths
When the MATCH
statement contains two or more path patterns which are connected by common elements, the final result is produced by taking the equi-join on the common element variables of the result sets from the different path patterns.
To retrieve Club
nodes (y
) which are connected with nodes (x
) that have relationships with both rowlock
and purplechalk
:
MATCH ({name: 'rowlock'})-(x)-({name: 'purplechalk'}), (x)-[]-(y:Club)
RETURN y
Result: y
_id | _uuid | schema | values |
---|---|---|---|
C01 | Sys-gen | Club | {since: 2005} |
Matching Disconnected Paths
When the MATCH
statement contains two or more disconnected path patterns (i.e., no common elements), the final result is produced by taking the Cartesian product of the result sets from the different path patterns.
To retrieve Club
nodes, and User
nodes who follow others after 2024-2-1
:
MATCH (c:Club), (u:User)-[f:Follows WHERE f.createdOn > '2024-2-1']->()
RETURN c._id, u.name
Result:
c._id | u.name |
---|---|
C02 | mochaeach |
C02 | purplechalk |
C01 | mochaeach |
C01 | purplechalk |
OPTIONAL MATCH
The difference between MATCH
and OPTIONAL MATCH
is in their handling of non-matching patterns:
MATCH
: If a pattern has no matches, no records will be returned.OPTIONAL MATCH
: If a pattern has no matches, it returns anull
value.
Keeping Records for All Subqueries
In both queries below, the variable u
is bound to three nodes (mocaheach
, rowlock
, and purplechalk
) that are connected to Brainy
in the first MATCH
statement. This variable u
is then referenced in the second MATCH
statement, which leads to subqueries. In each subquery, one node from u
is used to facilitate the path pattern matching. If a node does not result in a match, it will be excluded from subsequent parts of the query unless OPTIONAL MATCH
is used, which returns a value of null
instead.
MATCH (:User {name: "Brainy"})-[]-(u:User)
MATCH (u)-[:Joins]-(c:Club)
RETURN u.name, c._id
Result:
u.name | c._id |
---|---|
mochaeach | C02 |
MATCH (:User {name: "Brainy"})-[:Follows]-(u:User)
OPTIONAL MATCH (u)-[:Joins]-(c:Club)
RETURN u.name, c._id
Result:
u.name | c._id |
---|---|
purplechalk | null |
mochaeach | C02 |
rowlock | null |
Keeping the Query Running
In the case when a statement produces empty result, the query effectively halts at that point, as there is no data for subsequent statements to operate on.
In this query, the second MATCH
statement fails to find a match for purplechalk
joining a club, resulting in an empty working table. Consequently, the query terminates, and the subsequent MATCH
statement, which could have retrieved data, is not executed.
MATCH (n:User {name: "purplechalk"})
MATCH (n)-[:Joins]-(c:Club)
MATCH (m:User {name: "lionbower"})
RETURN n.name, c._id, m.name
Result: No Return Data
To prevent the query from terminating early, you can use OPTIONAL MATCH
as it enables the value null
to be passed to the next statement.
MATCH (n:User {name: "purplechalk"})
OPTIONAL MATCH (n)-[:Joins]-(c:Club)
MATCH (m:User {name: "lionbower"})
RETURN n.name, c._id, m.name
Result:
n.name | c._id | m.name |
---|---|---|
purplechalk | null |
lionbower |
Checking the Existence of Edges
This query returns users who have no followers:
MATCH (n:User)
OPTIONAL MATCH p = (n)<-[:Follows]-() WHERE p IS NULL
RETURN COLLECT_LIST(n.name) AS Names
Result:
Names |
---|
["mochaeach", "rowlock", "Brainy", "purplechalk", "lionbower"] |
MATCH YIELD
The YIELD
clause can be used to select specific node, edge, or path variables from the MATCH
statement, making them accessible for reference in subsequent parts of the query. Variables not selected with YIELD
will no longer be available. The YIELD
clause in the MATCH
statement does not support renaming variables using AS
. If the YIELD
clause is omitted, all variables are passed through by default.
This query only returns c
, as n
is not involved in YIELD
:
MATCH (n:User)-[:Joins]->(c:Club)
YIELD c
RETURN *
Result: c
_id | _uuid | schema | values |
---|---|---|---|
C01 | Sys-gen | Club | {since: 2005} |
C02 | Sys-gen | Club | {since: 2005} |
C01 | Sys-gen | Club | {since: 2005} |
This query returns n1
and e
, n2
is not included:
MATCH (n1:Club)
MATCH (n2:Club)<-[e:Joins WHERE e.memberNo < 3]-() YIELD e
RETURN *
n1
_id | _uuid | schema | values |
---|---|---|---|
C01 | Sys-gen | Club | {since: 2005} |
C01 | Sys-gen | Club | {since: 2005} |
C02 | Sys-gen | Club | {since: 2005} |
C02 | Sys-gen | Club | {since: 2005} |
e
_uuid |
_from |
_to |
_from_uuid |
_to_uuid |
schema |
values |
---|---|---|---|---|---|---|
Sys-gen | U02 | C01 | UUID of U02 | UUID of C01 | Joins | {memberNo: 1} |
Sys-gen | U02 | C01 | UUID of U02 | UUID of C01 | Joins | {memberNo: 1} |
Sys-gen | U05 | C01 | UUID of U05 | UUID of C01 | Joins | {memberNo: 2} |
Sys-gen | U05 | C01 | UUID of U05 | UUID of C01 | Joins | {memberNo: 2} |
This query throws syntax error since n2
is not selected in the YIELD
clause, thus it cannot be accessed by the RETURN
statement:
MATCH (n1:User), (n2:Club)
YIELD n1
RETURN n1, n2