GQL patterns

Graph Query Language (GQL) supports the following patterns. Patterns canbe used in aMATCH statement.

Pattern list

NameSummary
Graph patternA pattern to search for in a graph.
Element pattern Represents a node pattern or an edge pattern in a path pattern.
Subpath patternMatches a portion of a path.
Quantified path pattern A path pattern with a portion that can repeat within a specified range.
Label expression An expression composed from one or more graph label names in an element pattern.
Path search prefix Restricts path pattern to return all paths, any path, or a shortest path from each data partition.
Path mode Includes or excludes paths that have repeating edges.

Graph pattern

graph_pattern:path_pattern_list [where_clause ]path_pattern_list:top_level_path_pattern[, ...]top_level_path_pattern:  [path_variable = ] [ {path_search_prefix |path_mode } ]path_patternpath_pattern:path_term[ ...]subpath_pattern:  ( [path_mode ]path_pattern [where_clause ] )path_term:  {path_primary |quantified_path_primary }path_primary:  {element_pattern    |subpath_pattern  }where_clause:  WHEREbool_expression

Description

A graph pattern consists of a list path patterns. You can optionallyinclude aWHERE clause. For example:

(a:Account)-[e:Transfers]->(b:Account)-- path patternWHEREa!=b-- WHERE clause

Definitions

  • path_pattern_list: A list of path patterns. For example, thefollowing list contains two path patterns:

    (a:Account)-[t:Transfers]->(b:Account),-- path pattern 1(a)<-[o:Owns]-(p:Person)-- path pattern 2
  • path_variable: A variable for a path. For example,p is apath variable:

    p=(a:Account)-[e:Transfers]->(b:Account)
  • path_search_prefix: a qualifier for a path pattern to return all paths, anypath, or any shortest path. For more information, seePath search prefix.

  • path_mode: Thepath mode for a path pattern. Used to filter outpaths that have repeating edges.

  • path_pattern: A path pattern that matches paths in a property graph.For example:

    (a:Account)-[e:Transfers]->(b:Account)
  • path_term: Anelement pattern or asubpath pattern in a path pattern.

  • subpath_pattern: A path pattern enclosed in parentheses. To learnmore, seeGraph subpath pattern.

  • quantified_path_primary: The quantified path pattern to add to thegraph query. To learn more, seeQuantified path pattern.

  • element_pattern: A node pattern or an edge pattern. To learn more, seeElement pattern definition.

  • where_clause: AWHERE clause, which filters the matched results. Forexample:

    MATCH(a:Account)->(b:Account)WHEREa!=b

    Boolean expressions can be used in aWHERE clause, includinggraph-specificpredicates andlogical operators. Use thefield access operator to access graph properties.

Examples

Note: The examples in this section reference a property graph calledFinGraph.

The following query matches all nodes:

GRAPHFinGraphMATCH(n)RETURNn.name,n.id/*-----------+ | name | id | +-----------+ | NULL | 7  | | NULL | 16 | | NULL | 20 | | Alex | 1  | | Dana | 2  | | Lee  | 3  | +-----------*/

The following query matches all directed edges:

GRAPHFinGraphMATCH()-[e]->()RETURNCOUNT(e.id)ASresults/*---------+ | results | +---------+ | 8       | +---------*/

The following query matches all directed edges in either direction:

GRAPHFinGraphMATCH()-[e]-()RETURNCOUNT(e.id)ASresults/*---------+ | results | +---------+ | 16      | +---------*/

The following query matches paths matching two path patterns:

GRAPHFinGraphMATCH(src:Account)-[t1:Transfers]->(mid:Account)-[t2:Transfers]->(dst:Account),(mid)<-[:Owns]-(p:Person)RETURNp.name,src.idASsrc_account_id,mid.idASmid_account_id,dst.idASdst_account_id/*---------------------------------------------------------+ | name | src_account_id | mid_account_id | dst_account_id | +---------------------------------------------------------+ | Alex | 20             | 7              | 16             | | Alex | 20             | 7              | 16             | | Dana | 16             | 20             | 7              | | Dana | 16             | 20             | 16             | | Lee  | 7              | 16             | 20             | | Lee  | 7              | 16             | 20             | | Lee  | 20             | 16             | 20             | +---------------------------------------------------------*/

The following query converts a GQL path to JSON. Only unblocked accounts areincluded in the results and the results have been truncated for readability.

GRAPHFinGraphMATCHp=(account:Account{is_blocked:false})-[transfer:Transfers]-(dst:Account)RETURNTO_JSON(p)asresults/*---------------------------------------------------------------------------------------+ | results                                                                               | +---------------------------------------------------------------------------------------+ | [{...,"properties":{...,"id":20,"is_blocked":false,"nick_name":"Rainy Day Fund"}},... | | [{...,"properties":{...,"id":7,"is_blocked":false,"nick_name":"Vacation Fund"}},...   | | [{...,"properties":{...,"id":7,"is_blocked":false,"nick_name":"Vacation Fund"}},...   | | [{...,"properties":{...,"id":20,"is_blocked":false,"nick_name":"Rainy Day Fund"}},... | | [{...,"properties":{...,"id":20,"is_blocked":false,"nick_name":"Rainy Day Fund"}},... | | [{...,"properties":{...,"id":7,"is_blocked":false,"nick_name":"Vacation Fund"}},...   | +---------------------------------------------------------------------------------------/*

Element pattern

Note: Syntax characters enclosed in double quotes ("") are literal andrequired.
element_pattern:  {node_pattern |edge_pattern  }node_pattern:  (pattern_filler)edge_pattern:  {full_edge_any |full_edge_left |full_edge_right |abbreviated_edge_any |abbreviated_edge_left |abbreviated_edge_right  }full_edge_any:  "-["pattern_filler "]-"full_edge_left:  "<-["pattern_filler "]-"full_edge_right:  "-["pattern_filler "]->"abbreviated_edge_any:  -abbreviated_edge_left:<-abbreviated_edge_right:  ->pattern_filler:  [graph_pattern_variable ]  [is_label_condition ]  [ {where_clause |property_filters } ]  [cost_expression ]is_label_condition:  { IS | : }label_expressioncost_expression:  COSTexpressionwhere_clause:  WHEREbool_expressionproperty_filters:  "{"element_property[, ...] "}"element_property:element_property_name :element_property_value

Description

An element pattern is either a node pattern or an edge pattern.

Definitions

  • node_pattern: a pattern to match nodes in a property graph. For example:

    (n:Person)-- Matches all Person nodes in a property graph.
    (c:City)-- Matches all City nodes in a property graph.
    ()-- Matches all nodes in a property graph.
  • edge_pattern: a pattern to match edges in a property graph. For example:

    -[LivesIn]->-- Matches all LivesIn edges in a property graph.
    -[]->-- Matches all right directed edges in a property graph.
    (n:Person)-(c:City)-- Matches edges between Person and City nodes in any direction.

    There are several types of edge patterns:

    • full_edge_any: Any-direction edge with an optional pattern filler.
    • abbreviated_edge_any: Any-direction edge, no pattern filler.
    -[e:Located_In]--- Any-direction full edge with filler.-[]--- Any-direction full edge, no filler.--- Any-direction abbreviated edge.
    • full_edge_left: Left-direction edge with an optional pattern filler.
    • abbreviated_edge_left: Left-direction edge, no pattern filler.
    <-[e:Located_In]--- Left full edge with filler.<-[]--- Left full edge, no filler.<--- Left abbreviated edge.
    • full_edge_right: Right-direction edge with an optional pattern filler.
    • abbreviated_edge_right: Right-direction edge, no pattern filler.
    -[e:Located_In]->-- Right full edge with filler.-[]->-- Right full edge, no filler.->-- Right abbreviated edge.
  • pattern_filler: A pattern filler represents specifications on the node oredge pattern that you want to match. A pattern filler can optionally containgraph_pattern_variable,is_label_condition,

    where_clause orproperty_filters, and a cost expression. For example:

    (p:PersonWHEREp.name='Kai')

  • graph_pattern_variable: A variable for the pattern filler.You can use a graph pattern variable to reference the elementit's bound to in a linear graph query.

    p is the variable for the graph pattern elementp:Person in thefollowing example:

    (p:Person)-[:Located_In]->(c:City),(p)-[:Knows]->(p:PersonWHEREp.name='Kai')
  • is_label_condition: Alabel expression that the matched nodes and edgesmust satisfy. This condition includeslabel expression. You can useeitherIS or: to begin a condition. For example, these are the same:

    (pISPerson)
    (p:Person)
    -[ISKnows]->
    -[:Knows]->
  • label_expression: The expression for the label. For more information,seeLabel expression definition.

  • where_clause: AWHERE clause, which filters the nodes or edges that werematched.

    Boolean expressions are supported, including graph-specificpredicatesandlogical operators.

    TheWHERE clause can't reference properties when the graph pattern variableis absent.

    Use thefield access operator to accessgraph properties.

    Examples:

    (m:MusicCreatorWHEREm.name='Cruz Richards')
    (s:Singer)->(album:Album)<-(s2)WHEREs.name!=s2.name
    (s:Singer)-[has_friend:Knows]->(s2:SingerWHEREs2.singer_name='Mahan Lomond')
  • cost_expression: An optional expression for an edge pattern. This expressionis used to calculate the total compute cost of a path when used with theANY CHEAPEST path searchprefixes. The expression must evaluate to a finite positive number.COSTcan be applied only to edge patterns. For more information, seePath searchprefix.

    Example

    GRAPHFinGraphMATCHANYCHEAPEST(a)-[e:TransferCOSTe.amount]->{1,3}(b)RETURNa.id,b.id

  • property_filters: Filters the nodes or edges that were matched. It containsa key value map of element properties and their values. Property filters canappear in both node and edge patterns.

    Examples:

    {name:'Cruz Richards'}
    {last_name:'Richards',albums:2}
  • element_property: An element property inproperty_filters. The sameelement property can be included more than once in the sameproperty filter list. Element properties can be included in any order in aproperty filter list.

    • element_property_name: An identifier that represents the name of theelement property. The property that is identified must be defined in thegraph element unless the graph element hasdynamic properties. For more information about using the graph element withdynamic properties, seegraph-element-type.

    • element_property_value: A scalar expression that represents the value forthe element property. It must be equal to the property value for the filterto match. This value can be aNULL literal, but theNULL literal isinterpreted as= NULL, notIS NULL when the element property filter isapplied.

    Examples:

    (n:Person{age:20})
    (n:Person{id:n.age})
    (n1:Person)-[e:Owns{since:2023}]->(n2:Account)
    (:Person{id:100,age:20})-[e:Knows]->(n2:Person)
    (n:Person|Student{id:n.age+n.student_id})
    (n:Person{age:20,id:30})
    (n{id:100,age:20})
    (n:Person{id:10+n.age})-[e:Knows{since:2023+e.id}]->

    The following are equivalent:

    (n:PersonWHEREn.id=100ANDn.age=20)
    (n:Person{id:100,age:20})

    The following are equivalent:

    (a:Employee{employee_id:10})->(:University)<-(a:Alumni{alumni_id:20})
    (a:Employee&Alumni{employee_id:10,alumni_id:20})->(:University)<-(a:Employee&Alumni{employee_id:10,alumni_id:20})

    Although aNULL literal can be used as property value in theproperty filter, the semantics is= NULL, notIS NULL.This distinction is important when you create an element pattern:

    (n:Person{age:NULL})-- '= NULL'(n:PersonWHEREn.age=NULL)-- '= NULL'(n:PersonWHEREn.ageISNULL)-- 'IS NULL'

    The following produce errors:

    -- Error: The property specification for n2 can't reference properties in-- e and n1.(n1:Person)-[e:Knows]->(n2:Person{id:e.since+n1.age})
    -- Error: Aggregate expressions aren't allowed.(n:Person{id:SUM(n.age)})
    -- Error: An element property filter list can't be empty(n:Person{})

Details

Nodes and edges matched byelement pattern are referred to as graph elements.Graph elements can be used in GQLpredicates,functionsand subqueries within GQL.

Set operations support graph elements that have a commonsupertype.

Examples

Note: The examples in this section reference a property graph calledFinGraph.

The following query matches all nodes in the graph.n is a graph patternvariable that's bound to the matching nodes:

GRAPHFinGraphMATCH(n)RETURNLABELS(n)ASlabel/*-----------+ | label     | +-----------+ | [Account] | | [Account] | | [Account] | | [Person]  | | [Person]  | | [Person]  | +-----------*/

The following query matches all edges in the graph.e is a graph pattern variable that's bound to the matching edges:

GRAPHFinGraphMATCH-[e]->RETURNe.id/*----+ | id | +----+ | 20 | | 7  | | 7  | | 20 | | 16 | | 1  | | 3  | | 2  | +----*/

The following queries matches all nodes with a given label in the graph.n isa graph pattern variable that's bound to the matching nodes:

GRAPHFinGraphMATCH(n:Person)RETURNn.name,n.id/*-----------+ | name | id | +-----------+ | Alex | 1  | | Dana | 2  | | Lee  | 3  | +-----------*/
GRAPHFinGraphMATCH(n:Person|Account)RETURNn.id,n.name,n.nick_name/*----------------------------+ | id | name | nick_name      | +----------------------------+ | 7  | NULL | Vacation Fund  | | 16 | NULL | Vacation Fund  | | 20 | NULL | Rainy Day Fund | | 1  | Alex | NULL           | | 2  | Dana | NULL           | | 3  | Lee  | NULL           | +----------------------------*/

The following query matches all edges in the graph that have theOwns label.e is a graph pattern variable that's bound to the matching edges:

GRAPHFinGraphMATCH-[e:Owns]->RETURNe.id/*----+ | id | +----+ | 1  | | 3  | | 2  | +----*/

In the following query, theWHERE clause is used to filter out nodes whosebirthday property is no greater than1990-01-10:

GRAPHFinGraphMATCH(n:PersonWHEREn.birthday >'1990-01-10')RETURNn.name/*------+ | name | +------+ | Alex | +------*/

In the following query, theWHERE clause is used to only include edges whosecreate_time property is greater than2020-01-14 and less than2020-05-14:

GRAPHFinGraphMATCH-[e:OwnsWHEREe.create_time >'2020-01-14'ANDe.create_time <'2020-05-14']->RETURNe.id/*----+ | id | +----+ | 2  | | 3  | +----*/

In the following query, thePROPERTY_EXISTS predicate is used to only include nodesthat have aname property:

GRAPHFinGraphMATCH(n:Person|AccountWHEREPROPERTY_EXISTS(n,name))RETURNn.id,n.name/*-----------+ | id | name | +-----------+ | 1  | Alex | | 2  | Dana | | 3  | Lee  | +-----------*/

You can filter graph elements with property filters. The following queryuses a property filter,{is_blocked: false}, to only include elementsthat have theis_blocked property set asfalse:

GRAPHFinGraphMATCH(a:Account{is_blocked:false})RETURNa.id/*----+ | id | +----+ | 7  | | 20 | +----*/

You can use multiple property element filters to filter results. The followingquery uses the property element filter list,{is_blocked: false, nick_name: 'Vacation Fund'}to only include elements that have theis_blocked property set asfalseand thenick_name property set asVacation Fund:

GRAPHFinGraphMATCH(a:Account{is_blocked:false,nick_name:'Vacation Fund'})RETURNa.id/*----+ | id | +----+ | 7  | +----*/

The following query matches right directedTransfers edges connecting twoAccount nodes.

GRAPHFinGraphMATCH(src:Account)-[transfer:Transfers]->(dst:Account)RETURNsrc.idASsrc_id,transfer.amount,dst.idASdst_id/*--------------------------+ | src_id | amount | dst_id | +--------------------------+ | 7      | 300    | 16     | | 7      | 100    | 16     | | 16     | 300    | 20     | | 20     | 500    | 7      | | 20     | 200    | 16     | +--------------------------*/

The following query matches any directionTransfers edges connecting twoAccount nodes.

GRAPHFinGraphMATCH(src:Account)-[transfer:Transfers]-(dst:Account)RETURNsrc.idASsrc_id,transfer.amount,dst.idASdst_id/*--------------------------+ | src_id | amount | dst_id | +--------------------------+ | 16     | 300    | 7      | | 16     | 100    | 7      | | 20     | 300    | 7      | | 7      | 500    | 16     | | 7      | 200    | 16     | | 20     | 300    | 16     | | 20     | 100    | 16     | | 16     | 300    | 20     | | 7      | 500    | 20     | | 16     | 200    | 20     | +--------------------------*/

The following query matches left directed edges connectingPerson nodes toAccount nodes, using the left directed abbreviated edge pattern.

GRAPHFinGraphMATCH(account:Account)<-(person:Person)RETURNaccount.id,person.name/*------------+ | id  | name | +------------+ | 7   | Alex | | 20  | Dana | | 16  | Lee  | +------------*/

You can reuse variable names in patterns. The same variable name binds to thesame node or edge. The following query reuses a variable calleda:

GRAPHFinGraphMATCH(a:Account)-[t1:Transfers]->(mid:Account)-[t2:Transfers]->(a:Account)RETURNa.idASa_id/*------+ | a_id | +------+ | 16   | | 20   | +------*/

In the following query,a anda2 are different variable names but can matchthe same node:

GRAPHFinGraphMATCH(a:Account)-[t1:Transfers]->(mid:Account)-[t2:Transfers]->(a2)RETURNa.idASa_id,a2.idASa2_id/*--------------+ | a_id | a2_id | +--------------+ | 20   | 16    | | 20   | 16    | | 7    | 20    | | 7    | 20    | | 20   | 20    | | 16   | 7     | | 16   | 16    | +--------------*/

You need to explicitly apply theWHERE filter if you only want to match a pathifa anda2 are different. For example:

GRAPHFinGraphMATCH(a:Account)-[t1:Transfers]->(mid:Account)-[t2:Transfers]->(a2)WHEREa.id!=a2.idRETURNa.idASa_id,a2.idASa2_id/*--------------+ | a_id | a2_id | +--------------+ | 20   | 16    | | 20   | 16    | | 7    | 20    | | 7    | 20    | | 16   | 7     | +--------------*/

Subpath pattern

A subpath pattern matches a portion of a path. You can create a subpath patternby enclosing a portion of a path pattern within parentheses. A subpath patterncan contain inner subpath patterns.

Rules

  • A subpath pattern can be combined with node patterns, edge patterns, orother subpaths on either end.
  • The portion of a path pattern enclosed within a subpath pattern must adhereto the same rules as a standard path pattern
  • A subpath pattern can contain subpath patterns. This results inouter subpath patterns and inner subpath patterns.
  • Inner subpath patterns are resolved first, followed byouter subpath patterns, and then the rest of the path pattern.
  • If a variable is declared outside of a subpath pattern, itcan't be referenced inside the subpath pattern.
  • If a variable is declared inside of a subpath pattern, it canbe referenced outside of the subpath pattern.

Details

When you execute a query, an empty node pattern is added to the beginningand ending inside a subpath if the beginning and ending don't already havenode patterns. For example:

BeforeAfter
(node edge node)(node edge node)
(edge node)(empty_node edge node)
(node edge)(node edge empty_node)
(edge)(empty_node edge empty_node)

If this results in two node patterns that arenext to each other or a node pattern is next to a subpath, aSAME operationis performed on to the consecutive node patterns.

The following are examples of subpath patterns:

-- Success: e and p are both declared within the same subpath pattern and-- can be referenced in that subpath pattern.(-[e:LocatedIn]->(p:Person)->(c:City)WHEREp.id=e.id)
-- Success: e and p are both declared within the same subpath pattern-- hierarchy and can be referenced inside of that subpath pattern hierarchy.(-[e:LocatedIn]->((p:Person)->(c:City))WHEREp.id=e.id)
-- Error: e is declared outside of the inner subpath pattern and therefore-- can't be referenced inside of the inner subpath pattern.(-[e:LocatedIn]->((p:Person)->(c:City)WHEREp.id=e.id))
-- Success: e and p are declared in a subpath pattern and can be used outside-- of the subpath pattern.(-[e:LocatedIn]->(p:Person))->(c:City)WHEREp.id=e.id
-- No subpath patterns:(p:Person)-[e:LocatedIn]->(c:City)-[s:StudyAt]->(u:School)
-- One subpath pattern on the left:((p:Person)-[e:LocatedIn]->(c:City))-[s:StudyAt]->(u:School)
-- One subpath pattern on the right:(p:Person)-[e:LocatedIn]->((c:City)-[s:StudyAt]->(u:School))
-- One subpath pattern around the entire path pattern:((p:Person)-[e:LocatedIn]->(c:City)-[s:StudyAt]->(u:School))
-- One subpath pattern that contains only a node pattern:((p:Person))-[e:LocatedIn]->(c:City)-[s:StudyAt]->(u:School)
-- One subpath pattern that contains only an edge pattern:(p:Person)(-[e:LocatedIn]->)(c:City)-[s:StudyAt]->(u:School)
-- Two subpath patterns, one inside the other:((p:Person)(-[e:LocatedIn]->(c:City)))-[s:StudyAt]->(u:School)
-- Three consecutive subpath patterns:((p:Person))(-[e:LocatedIn]->(c:City))(-[s:StudyAt]->(u:School))

Examples

Note: The examples in this section reference a property graph calledFinGraph.

In the following query, the subpath(src:Account)-[t1:Transfers]->(mid:Account) is evaluated first, then the restof the path pattern:

GRAPHFinGraphMATCH((src:Account)-[t1:Transfers]->(mid:Account))-[t2:Transfers]->(dst:Account)RETURNsrc.idASsrc_account_id,mid.idASmid_account_id,dst.idASdst_account_id/*--------------------------------------------------+ | src_account_id | mid_account_id | dst_account_id | +--------------------------------------------------+ | 20             | 7              | 16             | | 20             | 7              | 16             | | 7              | 16             | 20             | | 7              | 16             | 20             | | 20             | 16             | 20             | | 16             | 20             | 7              | | 16             | 20             | 16             | +--------------------------------------------------*/

Quantified path pattern

Note: Syntax characters enclosed in double quotes ("") are literal andrequired.
quantified_path_primary:path_primary  {fixed_quantifier |bounded_quantifier }fixed_quantifier:  "{"bound "}"bounded_quantifier:  "{" [lower_bound ],upper_bound "}"

Description

A quantified path pattern is a path pattern with a portion that can repeatwithin a specified range. You can specify the range, using a quantifier. Aquantified path pattern is commonly used to match variable-length paths.

Definitions

  • quantified_path_primary: The quantified path pattern to add to the graphquery.

  • path_primary: The portion of a path pattern to be quantified.

  • fixed_quantifier: The exact number of times the path pattern portion mustrepeat.

    • bound: A positive integer that represents the exact number of repetitions.
  • bounded_quantifier: The minimum and maximum number of times the path patternportion can repeat.

    • lower_bound: A non-negative integer that represents the minimum number oftimes that the path pattern portion must repeat. If a lower bound isn'tprovided, 0 is used by default.

    • upper_bound: A positive integer that represents the maximum number oftimes that the path pattern portion can repeat. This number must bespecified and be equal to or greater thanlower_bound.

Details

  • A path must have aminimum node count greater than 0. The minimum nodecount of a quantified portion within the path is calculated as:

    min_node_count = lower_quantifier * node_count_of_quantified_path

    Whenbound orlower_bound of the quantified path pattern portion is 0,the path must contain other parts withminimum node count greater than 0.

  • A quantified path must have aminimum path length greater than 0. Theminimum path length of a quantified path is calculated as:

    min_path_length = lower_quantifier * length_of_quantified_path

    The path length of a node is 0. The path length of an edge is 1.

  • A quantified path pattern withbounded_quantifier matches paths of anylength between the lower and the upper bound. This is equivalent to unioningmatch results from multiple quantified path patterns withfixed_quantifier,one for each number between the lower bound and upper bound.

  • Quantification is allowed on an edge or subpath. When quantifying an edge,the edge pattern is canonicalized into a subpath.

    -[]->{1, 5}

    is canonicalized into

    (()-[]->()){1, 5}
  • Multiple quantifications are allowed in the same graph pattern, however,quantifications may not be nested.

  • Only singleton variables can be multiply-declared. A singleton variable is avariable that binds exactly to one node or edge.

    In the followingMATCH statement, the variablesp,knows, andf aresingleton variables, which bind exactly to one element each.

    MATCH(p)-[knows]->(f)
  • Variables defined within a quantified path pattern bind to an array ofelements outside of the quantified path pattern and are called groupvariables.

    In the followingMATCH statement, the path pattern has the quantifier{1, 3}. The variablesp,knows, andf are each bind to an array ofelements in theMATCH statement result and are considered group variables:

    MATCH((p)-[knows]->(f)){1,3}

    Within the quantified pattern, before the quantifier is applied,p,knows,andf each bind to exactly one element and are considered singletonvariables.

Examples:

-- Quantified path pattern with a fixed quantifier:MATCH((p:Person)-[k:Knows]->(f:Person)){2}-- Equivalent:MATCH((p0:Person)-[k0:Knows]->(f0:Person)(p1:Person)-[k1:Knows]->(f1:Person))
-- Quantified path pattern with a bounded quantifier:MATCH((p:Person)-[k:Knows]->(f:Person)){1,3}-- Equivalent:MATCH((p:Person)-[k:Knows]->(f:Person)){1}UNIONALLMATCH((p:Person)-[k:Knows]->(f:Person)){2}UNIONALLMATCH((p:Person)-[k:Knows]->(f:Person)){3}
-- Quantified subpath with default lower bound (0) and an upper bound.-- When subpath is repeated 0 times, the path pattern is semantically equivalent-- to (source_person:Person)(dest_person:Person).MATCH(source_person:Person)((p:Person)-[k:Knows]->(f:Person)){,4}(dest_person:Person)
-- Edge quantification is canonicalized into subpath quantification:MATCH(p:Person)-[k:Knows]->{1,2}(f:Person)-- Equivalent:MATCH(p:Person)(()-[k:Knows]->()){1,2}(f:Person)
-- ERROR: Minimum path length for the quantified path is 0.MATCH(p:Person){1,3}
-- ERROR: Minimum node count and minimum path length for the entire path is 0.MATCH((p:Person)-[k:Knows]->(f:Person)){0}
-- ERROR: Minimum path length for the entire path is 0 when quantified portion-- is repeated 0 times.MATCH(:Person)((p:Person)-[k:Knows]->(f:Person)){0,3}
-- ERROR: `p` is declared once as a group variable and once as a singleton-- variable.MATCH(s:Person)((p:Person)-[k:Knows]->(f:Person)){1,3}->(p:Person)
-- ERROR: `p` is declared twice as a group variable.MATCH((p:Person)-[k:Knows]->(f:Person)){1,3}-[x.Knows]->((p:Person)-[z:Knows]-(d:Person)){2}
-- Since both declarations of `p` are within the quantifier’s pattern,-- they are treated as singleton variables and can be multiply-declared.MATCH(s:person)((p:Person)-[k:Knows]->(p:Person)){1,3}

Examples

Note: The examples in this section reference a property graph calledFinGraph.

The following query uses a quantified path pattern to match all of thedestination accounts that are one to three transfers away from a source accountwithid equal to7:

GRAPHFinGraphMATCH(src:Account{id:7})-[e:Transfers]->{1,3}(dst:Account)WHEREsrc!=dstRETURNARRAY_LENGTH(e)AShops,dst.idASdst_account_id/*-----------------------+ | hops | dst_account_id | +-----------------------+ | 1    | 16             | | 3    | 16             | | 3    | 16             | | 1    | 16             | | 2    | 20             | | 2    | 20             | +-----------------------*/

The following query uses a quantified path pattern to match paths betweenaccounts with one to two transfers through intermediate accounts that areblocked:

GRAPHFinGraphMATCH(src:Account)((:Account)-[:Transfers]->(mid:Account{is_blocked:true})){1,2}-[:Transfers]->(dst:Account)RETURNsrc.idASsrc_account_id,dst.idASdst_account_id/*---------------------------------+ | src_account_id | dst_account_id | +---------------------------------+ | 7              | 20             | | 7              | 20             | | 20             | 20             | +---------------------------------*/

In the following query,e is declared in a quantified path pattern. Whenreferenced outside of that pattern,e is a group variable bound to an arrayofTransfers. You can use the group variable in aggregate functions suchasSUM andARRAY_LENGTH:

GRAPHFinGraphMATCH(src:Account{id:7})-[e:TransfersWHEREe.amount >100]->{0,2}(dst:Account)WHEREsrc.id!=dst.idLETtotal_amount=SUM(e.amount)RETURNsrc.idASsrc_account_id,dst.idASdst_account_id,ARRAY_LENGTH(e)ASnumber_of_hops,total_amount/*-----------------------------------------------------------------+ | src_account_id | dst_account_id | number_of_hops | total_amount | +-----------------------------------------------------------------+ | 7              | 16             | 1              | 300          | | 7              | 20             | 2              | 600          | +-----------------------------------------------------------------*/

Label expression

label_expression:  {label_name    |or_expression    |and_expression    |not_expression  }

Description

A label expression is formed by combining one or more labels with logicaloperators (AND, OR, NOT) and parentheses for grouping.

Definitions

  • label_name: The label to match. Use% to match any label in thegraph. For example:

    (p:Person)
    (p:%)
  • or_expression:GQL logicalOR operation forlabel expressions. For example:

    (p:(Singer|Writer))
    (p:(Singer|(Producer|Writer)))
    (p:(Singer|(Producer&Writer)))
  • and_expression:GQL logicalAND operation forlabel expressions. For example:

    (p:(Singer&Producer))
    (p:(Singer&(Writer|Producer)))
    (p:(Singer&(Writer&Producer)))
  • not_expression:GQL logicalNOT operation forlabel expressions. For example:

    (p:!Singer)
    (p:(!Singer&!Writer))
    (p:(Singer|(!Writer&!Producer)))

Details

If a label in defined in the schema, it exposes a set of propertieswith declared names and data types. When a node or edge carries thislabel, the properties exposed by that label are always accessible throughthe node or edge.

Labels can also be modeled from column values using thedynamic label definition. A dynamic label for a nodeor edge is managed using the column value, without requiring schema changes.A dynamic label isn't associated with any defined properties in the schema.

Examples

Note: The examples in this section reference a property graph calledFinGraph.

The following query matches all nodes with the labelPersonin theFinGraph property graph.

GRAPHFinGraphMATCH(n:Person)RETURNn.name/*------+ | name | +------+ | Alex | | Dana | | Lee  | +------*/

The following query matches all nodes that have either aPersonor anAccount label in theFinGraph property graph.

GRAPHFinGraphMATCH(n:Person|Account)RETURNn.id/*----+ | id | +----+ | 7  | | 16 | | 20 | | 1  | | 2  | | 3  | +----*/

Path search prefix

path_search_prefix:  {    ALL    | ANY    | ANY SHORTEST    | ANY CHEAPEST  }

Description

Restricts path pattern to return all paths, any path, or a shortest path fromeach data partition.

Definitions

  • ALL (default) : Returns all paths matching the path pattern. This is thedefault value when no search prefix is specified.
  • ANY: Returns any path matching the path pattern from each data partition.
  • ANY SHORTEST: Returns a shortest path (the path with the least number ofedges) matching the path pattern from each data partition. If there are morethan one shortest paths per partition, returns any one of them.
  • ANY CHEAPEST: Returns one of the cheapest paths matching the path patternfrom each data partition. A cheapest path is one with the minimum totalcompute cost, calculated fromCOST expressions on edges in the path.If multiple cheapest paths exist per partition, returns any one ofthe paths.

Details

The path search prefix first partitions the match results by their endpoints(the first and last nodes) then selects paths from each group.

TheANY andANY SHORTEST prefixes can return multiple paths, onefor each distinct pair of endpoints.

When using prefixes other thanALL in a path pattern, don't reusevariables defined within that pattern elsewhere in the sameMATCH statement,unless the variable represents an endpoint. Each prefix needs to operateindependently on its associated path pattern.

Path cost expression

When you use theANY CHEAPESTparameter, edge patterns in thepath expression can include a cost expression usingCOST <expr>. The totalcompute cost of a path is the sum of costs of edges that haveCOSTexpressions.

To useANY CHEAPEST in a query:

  • At least oneCOST expression must be defined within the path pattern.
  • All quantified edge patterns within the path pattern must include aCOST expression.
  • TheCOST expression must be used only on edge patterns.
  • All variables used by<expr> must be local to the edge pattern.
  • <expr> must be a numeric type:INT32,INT64,UINT32,UINT64,FLOAT,DOUBLE,NUMERIC, orBIGNUMERIC.
  • <expr> must evaluate to a finite positive number.NULL, zero, negativevalues,Inf, andNaN produce a runtime error.

Examples

Note: The examples in this section reference a property graph calledFinGraph.

The following query matches a shortest path between each pair of[a, b].

GRAPHFinGraphMATCHANYSHORTEST(a:Account{is_blocked:true})-[t:Transfers]->{1,4}(b:Account)LETpath_length=COUNT(t)RETURNa.idASa_id,path_length,b.idASb_id/*------+-------------+------+ | a_id | path_length | b_id | +------+-------------+------+ |   16 |           2 |   16 | |   16 |           2 |    7 | |   16 |           1 |   20 | +------+-------------+------*/

The following query matches any path between each pair of[a, b].

GRAPHFinGraphMATCHANY(a:Account{is_blocked:true})->(mid:Account)->(b:Account)RETURNa.idASa_id,mid.idASmid_id,b.idASb_id/*------+--------+------+ | a_id | mid_id | b_id | +------+--------+------+ | 16   | 20     | 16   | | 16   | 20     | 7    | +------+--------+------*/

The following query matches all paths between each pair of[a, b]. TheALLprefix doesn't filter out any result.

GRAPHFinGraphMATCHALL(a:Account{id:20})-[t:Transfers]->(b:Account)RETURNa.idASa_id,t.amount,b.idASb_id-- Equivalent:GRAPHFinGraphMATCH(a:Account{id:20})-[t:Transfers]->(b:Account)RETURNa.idASa_id,t.amount,b.idASb_id/*------+--------+------+ | a_id | amount | b_id | +------+--------+------+ | 20   | 500    | 7    | | 20   | 200    | 16   | +------+--------+------*/

The following query finds the middle account of any two-hop loops that starts andends with the same account withid = 20, and gets the middle account's owner.

GRAPHFinGraphMATCHANY(a:Account{id:20})->(mid:Account)->(a:Account)MATCHALL(p:Person)->(mid)RETURNp.name,mid.id/*------+----+ | name | id | +------+----+ | Lee  | 16 | +------+----*/

The following query produces an error becausemid, defined within a pathpattern with theANY prefix, can't be reused outside that pattern in thesameMATCH statement. This isn't permitted becausemid isn't an endpoint.

-- ErrorGRAPHFinGraphMATCHANY(a:Account{id:20})->(mid:Account)->(a:Account)->(mid:Account)->(a:Account),ALL(p:Person)->(mid)RETURNp.name

The following query succeeds becausea, even though defined in a path patternwith theANY path search prefix, can be reused outside of the path patternwithin the sameMATCH statement, sincea is an endpoint.

-- SucceedsGRAPHFinGraphMATCHANY(a:Account{id:20})->(mid:Account)->(a:Account)->(mid:Account)->(a:Account),ALL(p:Person)->(a)RETURNp.name/*------+ | name | +------+ | Dana | +------*/

The following query succeeds becausemid isn't reused outside of the pathpattern with theANY prefix in the sameMATCH statement.

-- SucceedsGRAPHFinGraphMATCHANY(a:Account{id:20})->(mid:Account)->(a:Account)->(mid:Account)->(a:Account)MATCHALL(p:Person)->(mid)RETURNp.name/*------+ | name | +------+ | Lee  | +------*/

All rules forquantified path patterns apply. In thefollowing examples, althoughp is on the boundary of the first path, it's agroup variable and still not allowed be declared again outside its parentquantified path:

-- ErrorGRAPHFinGraphMATCHANY((p:Person)->(f:Person)){1,3},ALL->(p)->RETURNp.name
-- ErrorGRAPHFinGraphMATCHANY((p:Person)->(f:Person)){1,3},ALL((p)->){1,3}RETURNp.name

The following query matches one of the cheapest paths between each pair of[a, b] based on transfer amount:

GRAPHFinGraphMATCHANYCHEAPEST(a:Account)-[t:TransfersCOSTt.amount]->{1,3}(b:Account)LETtotal_cost=sum(t.amount)RETURNa.idASa_id,b.idASb_id,total_cost/*------+------+------------+ | a_id | b_id | total_cost | +------+------+------------+ | 7    | 7    | 900        | | 7    | 16   | 100        | | 7    | 20   | 400        | | 16   | 7    | 800        | | 16   | 16   | 500        | | 16   | 20   | 300        | | 20   | 7    | 500        | | 20   | 16   | 200        | | 20   | 20   | 500        | +------+------+------------*/

Path mode

path_mode:  {    WALK [ PATH | PATHS ]    | ACYCLIC [ PATH | PATHS ]    | TRAIL [ PATH | PATHS ]  }

Description

Includes or excludes paths that have repeating edges based on the specifiedmode.

Definitions

  • WALK (default) : Keeps all paths. If the path mode isn't present,WALKis used by default.
  • ACYCLIC: Filters out paths that have repeating nodes.
  • TRAIL: Filters out paths that have repeating edges.
  • PATH andPATHS: Syntactic sugar that has no effect on execution.

Details

A path mode is typically added in order to filter out paths with duplicateedges or nodes. It can be applied to any path or subpath pattern.

A path mode is applied to the whole path or subpath pattern that it restricts,regardless of whether other modes are used on subpath patterns.

A path mode is applied to path patterns only, not graph patterns.

A path can have either a path mode or apath search prefix, butnot both.

Examples

Note: The examples in this section reference a property graph calledFinGraph.

The following query demonstrates the use of theWALK path mode on anon-quantified path pattern. The first path in the results uses the same edgefort1 andt3.

GRAPHFinGraphMATCHWALK(a1:Account)-[t1:Transfers]->(a2:Account)-[t2:Transfers]->(a3:Account)-[t3:Transfers]->(a4:Account)WHEREa1.id <a4.idRETURNt1.idastransfer1_id,t2.idastransfer2_id,t3.idastransfer3_id/*--------------+--------------+--------------+ | transfer1_id | transfer2_id | transfer3_id | +--------------+--------------+--------------+ | 16           | 20           | 16           | | 7            | 16           | 20           | | 7            | 16           | 20           | +--------------+--------------+--------------*/

The following queries demonstrate the use of theACYCLIC path mode on anon-quantified path pattern. Notice that the path whosea1 anda3 nodes areequal has been filtered out.

GRAPHFinGraphMATCHACYCLIC(a1:Account)-[t1:Transfers]->(a2:Account)-[t2:Transfers]->(a3:Account)RETURNa1.idasaccount1_id,a2.idasaccount2_id,a3.idasaccount3_id/*-------------+-------------+-------------+ | account1_id | account2_id | account3_id | +-------------+-------------+-------------+ | 20          | 7           | 16          | | 20          | 7           | 16          | | 7           | 16          | 20          | | 7           | 16          | 20          | | 16          | 20          | 7           | +-------------+-------------+-------------*/

The following queries demonstrate the use of theTRAIL path mode on anon-quantified path pattern. Notice that the path whoset1 andt3 edges areequal has been filtered out.

GRAPHFinGraphMATCHTRAIL(a1:Account)-[t1:Transfers]->(a2:Account)-[t2:Transfers]->(a3:Account)-[t3:Transfers]->(a4:Account)WHEREa1.id <a4.idRETURNt1.idastransfer1_id,t2.idastransfer2_id,t3.idastransfer3_id/*--------------+--------------+--------------+ | transfer1_id | transfer2_id | transfer3_id | +--------------+--------------+--------------+ | 7            | 16           | 20           | | 7            | 16           | 20           | +--------------+--------------+-------------*/

The following query demonstrates that path modes are applied on path patternsand not on graph patterns. Notice that, ifTRAIL was applied on the graphpattern then there would be zero results returned since edget1 is explicitlyduplicated. Instead, it's only applied on path pattern(a1)-[t1]-(a2).

GRAPHFinGraphMATCHTRAIL(a1)-[t1]-(a2),(a2)-[t1]-(a3)RETURNCOUNT(1)asnum_paths/*-----------+ | num_paths | +-----------+ | 16        | +-----------*/GRAPHFinGraphMATCHTRAIL(a1)-[t1]-(a2)-[t1]-(a3)RETURNCOUNT(1)asnum_paths/*-----------+ | num_paths | +-----------+ | 0         | +-----------*/

The following query demonstrates the use of theTRAIL path mode on aquantified path pattern. Notice thatTRAIL is applied on a path pattern thatis the concatenation of four subpath patterns of the form()-[:Transfers]->().

GRAPHFinGraphMATCHTRAIL(a1:Account)-[t1:Transfers]->{4}(a5:Account)RETURNCOUNT(1)asnum_paths/*-----------+ | num_paths | +-----------+ | 6         | +-----------*/

The following query demonstrates that path modes are applied individually on thepath or subpath pattern in which they are defined. In this example, theexistence ofWALK doesn't negate the semantics of the outerTRAIL. Noticethat the result is the same with the previous example whereWALK isn'tpresent.

GRAPHFinGraphMATCHTRAIL(WALK(a1:Account)-[t1:Transfers]->{4}(a5:Account))RETURNCOUNT(1)asnum_paths/*-----------+ | num_paths | +-----------+ | 6         | +-----------*/

The following query demonstrates the use of theTRAIL path mode on a subpathpattern. Notice thatTRAIL is applied on a path pattern that's theconcatenation of three subpath patterns of the form()-[:Transfers]->(). Sinceedget4 is outside this path pattern, it can be equal to any of the edges onit. Compare this result with the result of the previous query.

GRAPHFinGraphMATCH(TRAIL(a1:Account)-[t1:Transfers]->{3}(a4:Account))-[t4:Transfers]->(a5:Account)RETURNCOUNT(1)asnum_paths/*-----------+ | num_paths | +-----------+ | 14        | +-----------*/

The following query demonstrates the use of theTRAIL path mode within aquantified path pattern. Notice that the resulting path is the concatenation oftwo subpaths of the form()-[:Transfers]->()-[:Transfers]->()-[:Transfers]->(). Therefore each pathincludes six edges in total.TRAIL is applied separately on the edges of eachof the two subpaths. Specifically, the three edges on the first supath must bedistinct from each other. Similarly, the three edges on the second subpath mustalso be distinct from each other. However, there may be edges that are equalbetween the two subpaths.

GRAPHFinGraphMATCH(TRAIL-[t1:Transfers]->()-[t2:Transfers]->()-[t3:Transfers]->){2}RETURNCOUNT(1)asnum_paths/*-----------+ | num_paths | +-----------+ | 26        | +-----------*/

The following query demonstrates that there are no paths of length six withnon-repeating edges.

GRAPHFinGraphMATCHTRAIL-[:Transfers]->{6}RETURNCOUNT(1)asnum_paths/*-----------+ | num_paths | +-----------+ | 0         | +-----------*/

The following query demonstrates that a path can't have both a path mode and apath search prefix:

-- ErrorGRAPHFinGraphMATCHANYSHORTESTTRAIL->{1,4}RETURNCOUNT(1)asnum_paths

The following query demonstrates that path modes can coexist withpath search prefixes when the path mode is placed on a subpath.

GRAPHFinGraphMATCHANYSHORTEST(TRAIL->{1,4})RETURNCOUNT(1)asnum_paths/*-----------+ | num_paths | +-----------+ | 18        | +-----------*/

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-12-15 UTC.