Skip to content
Developer Edition runs on one host and does not require a product license file. Need multi-host deployment or performance testing at scale? Explore Enterprise Edition

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 GRAPH on the used schema or the action MATCH on 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, or SET on 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
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 ) , } = GRAPH { use_clause match_statement return_statement }

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
PROPERTY GRAPH graph_variable TYPED graph_type_name

graph_variable_definition_from_type ::=
     'PROPERTY'? 'GRAPH' graph_variable 'TYPED' graph_type_name

Clear a graph variable

graph_variable_clear
SET 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.

  1. 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)
    }
    '''
    
  2. Create a temporary graph and populate it with data.

    Create a temporary graph and insert 6 nodes (IDs 0–5) with initial val of 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.

  3. 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 val to 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
    }
    '''
    
  4. 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=1
    

    In 3 iterations, nodes 0, 1, and 2 were activated (in iterations 0, 1, and 2 respectively), so their val was incremented from 0 to 1. Nodes 3, 4, and 5 were never activated, so their val remains 0.