Graph variables¶
Graph variables are used to store subgraphs for querying and computation. The keyword GRAPH is used to define graph variables.
There are two ways to define a graph variable:
- From a graph query: Use a MATCH statement to retrieve a subgraph from an existing graph and store it in the graph variable.
- From a graph type: Declare a graph variable with a predefined graph type, then import data into it by using the IMPORT statement.
Prerequisites¶
- A graph is created. For more information, see CREATE GRAPH.
- You must be granted to perform the action
MATCH ANY GRAPHon the used schema or the actionMATCHon the graph that you want to query. For more information, see Roles and privileges.
Usage notes¶
- DML operations that modify stored graph data are not supported, such as
INSERT,DELETE, orSETon nodes, edges, or their properties. - Indexes or similar structures cannot be created on graph variables.
SET <graph_variable>.clear()is allowed. You can use it to clear a graph variable before re-importing data.
Syntax¶
Define a graph variable from a query¶
- graph_variable_definition_from_query
graph_variable_definition_from_query ::=
'PROPERTY'? 'GRAPH' graph_variable
( 'TYPED'? 'GRAPH' '{'
(
(('NODE' | 'VERTEX') 'TYPE'? node_type_name '(' node_type_filler ')')
|
(('EDGE' | 'RELATIONSHIP') 'TYPE'? edge_type_name
(
'(' source_node_type_name ')' '-[' edge_type_filler ']->' '(' destination_node_type_name ')'
|
'(' destination_node_type_name ')' '<-[' edge_type_filler ']-' '(' source_node_type_name ')'
|
'(' source_node_type_name ')' '~[' edge_type_filler ']~' '(' destination_node_type_name ')'
)
)
)
(
','
(
(('NODE' | 'VERTEX') 'TYPE'? node_type_name '(' node_type_filler ')')
|
(('EDGE' | 'RELATIONSHIP') 'TYPE'? edge_type_name
(
'(' source_node_type_name ')' '-[' edge_type_filler ']->' '(' destination_node_type_name ')'
|
'(' destination_node_type_name ')' '<-[' edge_type_filler ']-' '(' source_node_type_name ')'
|
'(' source_node_type_name ')' '~[' edge_type_filler ']~' '(' destination_node_type_name ')'
)
)
)
)*
'}' )? '=' 'GRAPH' '{' use_clause? match_statement return_statement '}'
Define a graph variable from a graph type¶
- graph_variable_definition_from_type
graph_variable_definition_from_type ::=
'PROPERTY'? 'GRAPH' graph_variable 'TYPED' graph_type_name
Clear a graph variable¶
- graph_variable_clear
graph_variable_clear ::=
'SET' graph_variable '.clear()'
Parameters¶
graph_variable¶
The name of the graph variable to be defined. graph_variable can be a regular identifier or a delimited identifier enclosed with backticks (`). For more information about identifiers, see Rules for naming identifiers.
node_type_name¶
The name of the node type in the graph variable to be defined. The specified node type must also appear in the subsequent MATCH and RETURN statements.
node_type_filler¶
The properties and labels of the node type in the graph variable to be defined.
The specified properties and labels must be consistent with those of the corresponding node type in the subsequent MATCH and RETURN statements.
For more information about this parameter, see the syntax diagram in CREATE GRAPH TYPE.
edge_type_name¶
The name of the edge type in the graph variable to be defined. The specified edge type must also appear in the subsequent MATCH and RETURN statements.
source_node_type_name¶
The name of the source node type of the edge type in the graph variable to be defined. The specified node type must also appear in the subsequent MATCH and RETURN statements.
destination_node_type_name¶
The name of the destination node type of the edge type in the graph variable to be defined. The specified node type must also appear in the subsequent MATCH and RETURN statements.
edge_type_filler¶
The properties and labels of the edge type in the graph variable to be defined.
The specified properties and labels must be consistent with those of the corresponding edge type specified in the subsequent MATCH and RETURN statements.
For more information about this parameter, see the syntax diagram in CREATE GRAPH TYPE.
use_clause¶
The USE clause that specifies the graph to be used in the MATCH statement. It can be omitted if the graph to be used is already set as the home graph. For more information, see USE clause.
match_statement¶
The MATCH statement that retrieves the subgraph to be stored in the graph variable. The subgraph must contain at least one node.
If either node_type_name or edge_type_name is specified, the corresponding node or edge type must be specified in the MATCH statement.
For more information, see MATCH statement.
return_statement¶
The RETURN statement that specifies the subgraph to be stored in the graph variable. The subgraph must include at least one node.
If either node_type_name or edge_type_name is specified, the corresponding node or edge type must be specified in the RETURN statement.
For more information, see RETURN statement.
graph_type_name¶
The name of an existing graph type. The graph variable is created with the structure defined by this graph type but contains no data. You can later import data into it by using the IMPORT statement.
Behaviors¶
Importing data into a graph variable¶
After defining a graph variable from a graph type, you can use the USE clause to switch to it and then use the IMPORT statement to populate it with data. Importing data into a non-empty graph variable is not allowed. To re-import data, you must first clear the graph variable using SET <graph_variable>.clear().
Clearing a graph variable¶
The SET <graph_variable>.clear() statement removes all nodes and edges from a graph variable. The graph variable itself and its type definition are preserved. After clearing, you can import new data into the graph variable.
Running procedures on a graph variable¶
After populating a graph variable with data, you can use the USE clause to switch to it and run procedures on it.
Examples¶
The following examples are based on the example dataset.
Define a graph variable from a query¶
'''
GRAPH g = GRAPH { USE movie MATCH (a@Actor) RETURN a }
USE g
MATCH (v)
RETURN v.id, v.name AS name
ORDER BY v.id
LIMIT 3
'''
The preceding statements define a graph variable g that stores all Actor nodes, and then query this variable to retrieve three nodes ordered by their IDs.
Return:
+------+---------------+
| v.id | name |
+------+---------------+
| 2 | Mark Hamill |
| 3 | Harrison Ford |
| 4 | Carrie Fisher |
+------+---------------+
Define a graph variable from a query with inline graph type definitions¶
Note
Graph variables with inline graph type definitions must have a default value (i.e., the = GRAPH { query } clause cannot be omitted). To define an empty graph variable, use a predefined named graph type instead. See Define a graph variable from a graph type.
'''
GRAPH g TYPED GRAPH {
NODE TYPE Actor (LABEL Person {id INT64 PRIMARY KEY, name STRING, birthDate DATE } ),
NODE TYPE Movie (LABEL Movie {id INT64 PRIMARY KEY, name STRING }),
EDGE TYPE Act (Actor)-[LABEL Act{}]->(Movie)
} = GRAPH { USE movie MATCH (n@Actor)-[r@Act]->(m@Movie) RETURN n, m, r }
USE g
MATCH (v1@Actor) -[e]-> (v2@Movie)
RETURN v1.name AS name
ORDER BY name
LIMIT 3
'''
The preceding statement defines a graph variable g with predefined node types Actor and Movie and an edge type Act. The graph variable g stores the nodes of the Actor and Movie types and the edges of the Act type retrieved in the MATCH statement.
Return:
+------------------+
| name |
+------------------+
| Aaron Eckhart |
| Ada Lonati |
| Adam Alexi-Malle |
+------------------+
Define a graph variable from a graph type¶
The following example defines an empty graph variable with a predefined graph type and imports data from table variables.
'''
-- Create the graph type
CREATE GRAPH TYPE IF NOT EXISTS empty_typed_gt AS {
NODE Person (
LABEL Person {
id INT PRIMARY KEY,
name STRING
}
),
EDGE Knows (Person)-[:Knows{
id INT,
MULTIEDGE KEY()
}]->(Person)
}
'''
'''
GRAPH g TYPED empty_typed_gt
USE g {
TABLE persons TYPED TABLE {id INT, name STRING} =
{id: 1, name: "Alice"},
{id: 2, name: "Bob"}
TABLE edges TYPED TABLE {src_id INT, dst_id INT, id INT} =
{src_id: 1, dst_id: 2, id: 10}
IMPORT INTO GRAPH {
NODE (p@Person{ id: id, name: name }) FROM persons,
EDGE (id:src_id)-[e@Knows{ id: id }]->(id:dst_id) FROM edges
}
MATCH (p@Person)-[e@Knows]->(q@Person)
RETURN p.id, p.name, q.id, q.name, e.id
ORDER BY e.id
}
'''
Return:
+------+--------+------+--------+------+
| p.id | p.name | q.id | q.name | e.id |
+------+--------+------+--------+------+
| 1 | Alice | 2 | Bob | 10 |
+------+--------+------+--------+------+
Clear a graph variable¶
The following example shows how to clear a graph variable and query it afterward.
'''
GRAPH g = GRAPH{ USE movie MATCH (a@Actor) RETURN a }
SET g.clear()
USE g
MATCH (v)
RETURN v.id, v.name
'''
After clearing, the graph variable contains no data, so the query returns an empty result:
+------+--------+
| v.id | v.name |
+------+--------+
+------+--------+
Run a procedure on a graph variable¶
The following example defines a graph variable, populates it with data, and then runs a procedure on it that uses active sets and aggregation.
'''
-- Create the procedure
CREATE OR REPLACE PROCEDURE proc_graph_active_set_agg() RETURNS (cnt INT) AS {
VALUE active_set ACTIVE_SET
VALUE cnt SumAgg<INT> = 0
MATCH (s@Actor) WHERE s.id < 5
FINALLY {
SET active_set = s
}
MATCH (v@Actor)
WHERE v IN active_set
PER NODE (v) {
SET @cnt += 1
}
RETURN @cnt
}
'''
'''
-- Run the procedure on a graph variable
GRAPH g = GRAPH{ USE movie MATCH (a@Actor) RETURN a }
USE g
CALL proc_graph_active_set_agg()
RETURN cnt
'''
Return:
+-----+
| cnt |
+-----+
| 3 |
+-----+
Iterative computation on a graph variable¶
The following example demonstrates an iterative computation pattern on a graph variable. In each iteration, one node (identified by the iteration index) is "activated" and its val property is incremented by 1. The results are exported to table variables, the graph variable is cleared, and the updated data is re-imported for the next iteration.
-
Create the graph type.
''' CREATE GRAPH TYPE IF NOT EXISTS gv_iter_gt AS { NODE Person ( LABEL Person { id INT PRIMARY KEY, val INT } ), EDGE Link (Person)-[:Link{ id INT, MULTIEDGE KEY() }]->(Person) } ''' -
Create a temporary graph and populate it with data.
Create a temporary graph and insert 6 nodes (IDs 0–5) with initial
valof 0, and 5 edges forming a chain (0→1→2→3→4→5).''' CREATE TEMPORARY GRAPH IF NOT EXISTS #gv_iter_base TYPED gv_iter_gt ''' ''' USE #gv_iter_base { TABLE nodes TYPED TABLE {id INT, val INT} = {id: 0, val: 0}, {id: 1, val: 0}, {id: 2, val: 0}, {id: 3, val: 0}, {id: 4, val: 0}, {id: 5, val: 0} TABLE edges TYPED TABLE {src INT, dst INT, eid INT} = {src: 0, dst: 1, eid: 1}, {src: 1, dst: 2, eid: 2}, {src: 2, dst: 3, eid: 3}, {src: 3, dst: 4, eid: 4}, {src: 4, dst: 5, eid: 5} IMPORT INTO GRAPH { NODE (p@Person{ id: id, val: val }) FROM nodes, EDGE (id: src)-[e@Link{ id: eid }]->(id: dst) FROM edges } } '''The resulting graph structure is:
(0)--1-->(1)--2-->(2)--3-->(3)--4-->(4)--5-->(5)Each node has
val: 0. -
Create the procedures.
Three procedures are needed: one for importing data into the graph variable, one for a single computation step, and one for the outer iteration loop.
Import procedure: Imports node and edge data from table variables into the graph variable.
''' CREATE OR REPLACE PROCEDURE gv_iter_import(nodes TABLE, edges TABLE) AS { IMPORT INTO GRAPH { NODE (p@Person{ id: id, val: val }) FROM nodes, EDGE (id: src)-[e@Link{ id: eid }]->(id: dst) FROM edges } } '''Step procedure: Performs a single computation step. It copies the current
valto a temporary aggregator, activates the node whose ID equals the iteration index, increments that node's value by 1, and exports all nodes and edges to table variables for the next iteration.''' CREATE OR REPLACE PROCEDURE gv_iter_step(iter INT, nodes TABLE, edges TABLE) AS { VALUE active_set ACTIVE_SET VALUE active_cnt SumAgg<INT> = 0 NODE VALUE next_val SumAgg<INT> = 0 -- Copy current val to the aggregator MATCH (v@Person) PER NODE (v) { SET v.@next_val = v.val } -- Activate the node whose ID equals the iteration index MATCH (v@Person) WHERE v.id = iter FINALLY { SET active_set = v } -- Increment the activated node's value MATCH (v@Person) WHERE v IN active_set PER NODE (v) { SET v.@next_val = v.val + 1 SET @active_cnt += 1 } -- Export all nodes and edges for the next iteration MATCH (v@Person) PER NODE (v) { EXPORT v.id AS id, v.@next_val AS val INTO nodes } MATCH (s@Person)-[e@Link]->(t@Person) PER PATH { EXPORT s.id AS src, t.id AS dst, e.id AS eid INTO edges } LOG_INFO("gv_iter_step iter=", iter, " active_cnt=", @active_cnt) } '''Outer procedure: Drives the iteration loop. It first exports the initial data from the source temporary graph into table variables and imports them into the graph variable. Then it iterates: in each step, it runs the computation, clears the graph variable, and re-imports the updated data.
''' CREATE OR REPLACE PROCEDURE gv_iter_outer(max_iter INT) RETURNS (id INT, val INT) AS { GRAPH g TYPED gv_iter_gt TABLE nodes TYPED TABLE {id INT, val INT} TABLE edges TYPED TABLE {src INT, dst INT, eid INT} VALUE iter = 0 -- Export initial data from the source temporary graph MATCH (v@Person) PER NODE (v) { EXPORT v.id AS id, v.val AS val INTO nodes } MATCH (s@Person)-[e@Link]->(t@Person) PER PATH { EXPORT s.id AS src, t.id AS dst, e.id AS eid INTO edges } -- Import initial data into the graph variable USE g CALL gv_iter_import(nodes, edges) FINISH SET nodes.clear() SET edges.clear() -- Iteration loop WHILE (iter < max_iter) THEN { USE g CALL gv_iter_step(iter, nodes, edges) FINISH IF (iter <> max_iter - 1) THEN { SET g.clear() USE g CALL gv_iter_import(nodes, edges) FINISH SET nodes.clear() SET edges.clear() } SET iter = iter + 1 } FOR r IN nodes RETURN r.id AS id, r.val AS val ORDER BY r.id } ''' -
Run the iterative computation.
Call the outer procedure on the source temporary graph to run 3 iterations:
''' USE #gv_iter_base CALL gv_iter_outer(3) RETURN id, val '''Return:
+----+-----+ | id | val | +----+-----+ | 0 | 1 | | 1 | 1 | | 2 | 1 | | 3 | 0 | | 4 | 0 | | 5 | 0 | +----+-----+ Log: 2026-03-16T10:14:11.570209 INFO - gv_iter_step iter=0 active_cnt=1 2026-03-16T10:14:11.606670 INFO - gv_iter_step iter=1 active_cnt=1 2026-03-16T10:14:11.634837 INFO - gv_iter_step iter=2 active_cnt=1In 3 iterations, nodes 0, 1, and 2 were activated (in iterations 0, 1, and 2 respectively), so their
valwas incremented from 0 to 1. Nodes 3, 4, and 5 were never activated, so theirvalremains 0.