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.
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:
name, age, createdOn).STRING, INT32, LOCAL DATETIME). See Property Value Types.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})
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)
A closed graph's graph type can come from three sources:
Syntax<graph type specification> ::= <inline graph type> | <inferred graph type> | <named graph type>
| Source | How you create it | Resulting graph |
|---|---|---|
| Inline graph type | CREATE GRAPH g1 { … } | Define the graph type inline and it embeds into the graph. |
| Inferred graph type | CREATE GRAPH g1 LIKE g2 | Copy g2's current graph type for g1. No binding. |
| Named graph type | CREATE GRAPH g1 TYPED gType | Bound 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:
LIKE, their schema can be altered directly on the graph. Changes apply only to this graph.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:
GQLCREATE 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:
GQLCREATE GRAPH g2 { NODE User (:Player {name STRING, bio VECTOR(1536)}), NODE Club ({name STRING}), EDGE FOLLOWS (User)-[{createdOn TIMESTAMP}]->(User), EDGE JOINS (User)-[]->(Club) }
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:
GQLCREATE 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.
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
Show node or edge types defined in the current graph:
GQLSHOW NODE TYPES SHOW EDGE TYPES
To inspect a single node or edge type:
GQLDESCRIBE 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:
| Field | Description |
|---|---|
type | NODE or EDGE. |
name | The name of the type. |
properties | The associated property definitions. |
source_types | For edges: a list of source node-type names from one allowed endpoint pair. Empty for nodes and for edges with no endpoint constraint. |
target_types | For 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.
Show labels in the current graph:
GQLSHOW LABELS SHOW NODE LABELS SHOW EDGE LABELS
To inspect a single label:
GQLDESCRIBE LABEL myLabel -- DESC is a shorthand for DESCRIBE DESC LABEL myLabel
Each label provides the following essential metadata:
| Field | Description |
|---|---|
label | The name of the label. |
type | The type of the label, NODE or EDGE. |
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})
A node or edge type can only be dropped when it has no dependent objects. Dependents include:
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.
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
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
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
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
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:
GQLALTER GRAPH g4 DETACH GRAPH TYPE