UltipaDocs
Products
Solutions
Resources
Company
Start Free Trial
UltipaDocs
Start Free Trial
  • Introduction
  • GQL vs Other Languages
    • Overview
    • Node and Edge Patterns
    • Path Patterns
    • Quantified Paths
    • Questioned Paths
    • Shortest Paths
    • Cheapest Paths
    • K-Hop Traversal
    • Graph Patterns
    • Overview
    • Open Graphs
    • Closed Graphs
    • Graph Types
    • Constraints
    • Projections
    • Storage Maintenance
    • Node and Edge IDs
    • INSERT
    • INSERT OVERWRITE
    • UPSERT
    • MERGE
    • SET
    • REMOVE
    • DELETE
    • FOREACH
    • LOAD CSV
    • Query Composition
    • Result Table and Visualization
    • MATCH
    • OPTIONAL MATCH
    • FILTER
    • LET
    • FOR
    • ORDER BY
    • LIMIT
    • SKIP
    • CALL
    • RETURN
    • Composite Query
    • NEXT
    • All Functions
    • Element Functions
    • Path Functions
    • Aggregate Functions
    • Mathematical Functions
    • Trigonometric Functions
    • String Functions
    • List Functions
    • Datetime Functions
    • Spatial Functions
    • Null Functions
    • Utility Functions
    • Type Conversion Functions
    • Table Functions
  • Operators
  • Predicates
    • Overview
    • CASE
    • LET Value Expression
    • Value Query Expression
    • Count Query Expression
    • List Expressions
    • Current Values
    • Index
    • Full-text Index
    • Vector Index
  • Transactions
  • Triggers
  • Query Management
  • Execution Plan
    • Variables
    • Values and Types
    • Comments
    • Reserved Words
    • Naming Conventions
    • Syntactic Notation
  • GQL Conformance
  1. Docs
  2. /
  3. ISO GQL
  4. /
  5. Graph Management

Closed Graphs

Overview

A closed graph is constrained by its graph type (or schema), which contains a list of node types and edge types. It imposes a strict framework that governs data writing: each node or edge belongs to exact one node or edge type. Closed graphs ensure consistent structure and guarantees high data integrity and consistency.

Node Types

A node type is a schema definition of nodes. Each node type is identified by a unique node type name and consists of a label set and a set of property types. Each node belongs to exact one node type.

Syntax
<node type> ::=
  "NODE" [ "TYPE" ] <node type name> "(" [ <implied labels> ] [ <property types> ] ")"

<implied labels> ::= ":" <label name> [ { "&" <label name> } ... ]

<property types> ::= "{" <property type> [ { "," <property type> } ... ] "}"

<property type> ::= <property name> <property value type> [ <constraint type> ]

The node type name automatically becomes a label. The label set of a node type is the union of its type name and optional implied labels. When no additional labels are specified, the type name is the only label.

Node Type
-- No implied labels specified, node type name is the only label
-- Label set is :User
NODE User ({name STRING})

-- One implied label specified
-- Label set is :User&Employee
NODE User (:Employee {name STRING})

-- Multiple implied labels specified
-- Label set is :User&Employee&Manager
NODE User (:Employee&Manager {name STRING})

A property type is the schema-level declaration of a single property belonging to a node type or edge type. It has three parts:

  • Property name: A unique identifier of the property within the type (e.g. name, age, createdOn).
  • Property value type: An explicit value type that all values of this property must conform to (e.g. STRING, INT32, LOCAL DATETIME). See Property Value Types.
  • Constraint type: Optional, additional validation rule on the property (e.g. NOT NULL). See Constraints.
GQL
-- 'name' must be a non-null string; 'age' must be an integer; no other properties are allowed
NODE User ({name STRING NOT NULL, age INTEGER})

Edge Types

An edge type is a schema definition of edges. Each edge type is identified by a unique edge type name and consists of one label and a set of property types. Each edge belongs to exact one edge type.

Syntax
<edge type> ::= 
  "EDGE" [ "TYPE" ] <edge type name> { <edge type pattern> | <edge type phrase> }

<edge type pattern> ::=
  "(" [ <source node type name> ] ")-[" [ <property types> ] "]->(" [ <destination node type name> ] ")"

<edge type phrase> ::=
  [ <property types> ] "CONNECTING" "(" <source node type name> < "->" | "TO" > <destination node type name> ")"

Unlike node types, edge types do not support implied labels — the edge type name is its only label. The property types follow the same rules as on node types.

An edge type can constrain its endpoints to defined node types. The pattern form accepts either () (any node) or (<NodeTypeName>) on each side; the phrase form CONNECTING (Source -> Destination) requires a node-type name on both sides.

-- Connects any node to any node, no properties
EDGE FOLLOWS ()-[]->()

-- Connects any node to any node, with property 'since' of type DATE
EDGE LIKES ()-[{since DATE}]->()

-- Both source and destination node type names are User
EDGE FOLLOWS (User)-[{since DATE}]->(User)

-- Source node type name is User, destination node type name is Company
EDGE WORKS_AT (User)-[{title STRING}]->(Company)

A single declaration constrains an edge type to one (source → target) pair. To allow the same edge type between more than one node-type pair, declare it multiple times under the same name with different endpoints. All declarations of the same name must share identical property types — only the endpoints may vary; the engine merges them into one edge type with a list of allowed endpoint pairs.

Edge Type
-- WORKS_AT accepts (Employee → Company) and (Contractor → Company)
EDGE WORKS_AT (Employee)-[{title STRING}]->(Company),
EDGE WORKS_AT (Contractor)-[{title STRING}]->(Company)

If the bodies differ, the engine will reject:

GQL
-- Error: property definitions differ
EDGE WORKS_AT (Employee)-[{title STRING}]->(Company),
EDGE WORKS_AT (Contractor)-[{title STRING, since DATE}]->(Company)

Creating Closed Graphs

A closed graph's graph type can come from three sources:

Syntax
<graph type specification> ::= 
  <inline graph type> | <inferred graph type> | <named graph type>
SourceHow you create itResulting graph
Inline graph typeCREATE GRAPH g1 { … }Define the graph type inline and it embeds into the graph.
Inferred graph typeCREATE GRAPH g1 LIKE g2Copy g2's current graph type for g1. No binding.
Named graph typeCREATE GRAPH g1 TYPED gTypeBound to a named graph type. The graph's schema is owned by gType.

The inline and LIKE forms do not create a named graph type in the database. To create a named graph type that other graphs can bind to. See Graph Types.

The two operational flavors evolve their schema very differently:

  • For graphs created with inline graph type or LIKE, their schema can be altered directly on the graph. Changes apply only to this graph.
  • For graphs that bound to named graph type, direct schema alteration is rejected, because the schema is owned by the named graph type. The error message points you to either alter the named graph type (which propagates to every bound graph) or detach from that graph type first.

Inline Graph Type

Define node and edge types directly in the CREATE GRAPH statement.

Syntax
<inline graph type> ::= "{" [ <element type> [ { "," <element type> }... ] ] "}"

<element type> = <node type> | <edge type>

Create a graph with inline graph type specification:

GQL
CREATE GRAPH g1 {
  NODE User ({name STRING, age UINT32}),
  NODE Club ({name STRING}),
  EDGE FOLLOWS ()-[{createdOn TIMESTAMP}]->(),
  EDGE JOINS ()-[]->()
}

You can also constrain edge type endpoints:

GQL
CREATE GRAPH g2 {
  NODE User (:Player {name STRING, bio VECTOR(1536)}),
  NODE Club ({name STRING}),
  EDGE FOLLOWS (User)-[{createdOn TIMESTAMP}]->(User),
  EDGE JOINS (User)-[]->(Club)
}

Inferred Graph Type

Copy the graph type from another closed graph. Only the schema (node and edge types) is copied, no data is included.

Syntax
<cloned graph type> ::= "LIKE" <graph name>

Create a graph with the same schema as g1:

GQL
CREATE GRAPH g3 LIKE g1

To clone both the schema and the data, use AS COPY OF instead (see Cloning Graphs). AS COPY OF does not bound the new graph to any named graph type. Same as LIKE.

Named Graph Type

Bind the graph to a named graph type. To create a named graph type, see graph types.

Syntax
<named graph type> ::= [ "::" | "TYPED" ] <graph type name>

Create a graph and bound its schema to the graph type gType:

GQL
-- Bare reference
CREATE GRAPH g3 gType

-- :: separator
CREATE GRAPH g3 :: gType

-- TYPED keyword
CREATE GRAPH g3 TYPED gType

Schema Inspection

Showing Node/Edge Types

Show node or edge types defined in the current graph:

GQL
SHOW NODE TYPES
SHOW EDGE TYPES

To inspect a single node or edge type:

GQL
DESCRIBE NODE TYPE Person
DESCRIBE EDGE TYPE Follows

-- DESC is a shorthand for DESCRIBE
DESC NODE TYPE Person
DESC EDGE TYPE Follows

Each row provides the following metadata:

FieldDescription
typeNODE or EDGE.
nameThe name of the type.
propertiesThe associated property definitions.
source_typesFor edges: a list of source node-type names from one allowed endpoint pair. Empty for nodes and for edges with no endpoint constraint.
target_typesFor edges: a list of target node-type names from one allowed endpoint pair. Empty for nodes and for edges with no endpoint constraint.

An edge type declared with multiple endpoint pairs renders as one row per pair, sharing the same type / name / properties but with different source_types / target_types.

Showing Labels

Show labels in the current graph:

GQL
SHOW LABELS
SHOW NODE LABELS
SHOW EDGE LABELS

To inspect a single label:

GQL
DESCRIBE LABEL myLabel

-- DESC is a shorthand for DESCRIBE
DESC LABEL myLabel

Each label provides the following essential metadata:

FieldDescription
labelThe name of the label.
typeThe type of the label, NODE or EDGE.

Schema Evolution

Creating Node/Edge Types

Create new node and edge types in the current graph:

GQL
-- Add node type Book
CREATE NODE Book ({name STRING, author STRING})

-- Add edge type PURCHASED
CREATE EDGE PURCHASED (User)-[{createdOn TIMESTAMP}]->(Book)

-- Skip if a node type with the same name already exists
CREATE NODE IF NOT EXISTS Book ({name STRING, author STRING})

-- Replace the existing node type with the same name
CREATE OR REPLACE NODE Book ({name STRING, author STRING, isbn STRING})

Dropping Node/Edge Types

A node or edge type can only be dropped when it has no dependent objects. Dependents include:

  • Existing nodes or edges of that type.
  • Named constraints registered on that type.
  • For node types: any edge type that references it as a source or destination endpoint. Drop such edge types first.

Drop node and edge types from the current graph:

GQL
-- Drop node type User
DROP NODE User

-- Drop edge type FOLLOWS
DROP EDGE FOLLOWS

-- Skip if the type does not exist
DROP NODE IF EXISTS Book

-- Drop the type along with its nodes and any constraints registered on it
DROP NODE User CASCADE

CASCADE removes the dependent nodes/edges and named constraints alongside the type, but does not drop other type definitions that depend on it — edge types referencing a node type as endpoint must be dropped explicitly first.

Renaming Node/Edge Types

Rename node and edge types in the current graph:

GQL
-- Rename node type User to People
ALTER NODE User RENAME TO People

-- Rename edge type FOLLOWS to LINKS
ALTER EDGE FOLLOWS RENAME TO LINKS

Adding Properties

Add properties to node and edge types in the current graph:

GQL
-- Add property gender to node type User
ALTER NODE User ADD PROPERTY gender STRING

-- Add property memberNo to edge type JOINS
ALTER EDGE JOINS ADD PROPERTY memberNo INT32

Renaming Properties

Rename node and edge properties in the current graph:

GQL
-- Rename property name to title for Book node type
ALTER NODE Book PROPERTY name RENAME TO title

-- Rename property memberNo to memberNumber for JOINS edge type
ALTER EDGE JOINS PROPERTY memberNo RENAME TO memberNumber

Dropping Properties

When a property is dropped, all related data - including the property values, associated indexes, and cached values - is permanently removed. Drop node and edge properties from the current graph:

GQL
-- Drop property name from node type User
ALTER NODE User DROP PROPERTY name

-- Drop property createdOn from edge type FOLLOWS
ALTER EDGE FOLLOWS DROP PROPERTY createdOn

Detaching from Named Graph Type

The operations above apply to graphs created with inline or inferred graph type. On a graph bound to a named graph type, these direct ops are rejected. To evolve only this graph independently, detach it from the bounded graph type first:

GQL
ALTER GRAPH g4 DETACH GRAPH TYPE