Source: https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/dml/insert/ Documentation version: v5.3.2 # INSERT statement The INSERT statement creates nodes and edges in a graph or temporary graph. Note An operation involving a non-default schema or an object in it requires access to the schema, either implicitly or through an explicit `USAGE` grant, as well as the privilege required for the operation. The schema access check and the privilege check for the requested operation are independent; satisfying one does not satisfy the other. Schema access control does not apply to temporary graphs or built-in procedures and functions. For more information, see [Schema access control](https://dev-docs.nebula-graph.io/v5.3.2/server-admin/authorization/schema-access-control/). ## Prerequisites - A graph or temporary graph is created. For more information, see [CREATE GRAPH](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/graph/create/) and [CREATE TEMPORARY GRAPH](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/graph-projection/create/). - To insert nodes and edges to a graph, you must be granted to perform the action `INSERT ANY GRAPH` on the used schema or the action `INSERT` on the resource object that you want to insert. For more information, see [Roles and privileges](https://dev-docs.nebula-graph.io/v5.3.2/server-admin/authorization/). - To insert nodes and edges to a temporary graph, you must be the user with the role `ADMIN` or the owner of the temporary graph. ## Syntax diagramsource insert_statement insert_path_pattern insert_element_pattern_filler insert_edge_pattern ```` insert_statement ::= ( 'INSERT' | 'INSERT' 'OR' 'REPLACE' | 'INSERT' 'OR' 'IGNORE' | 'INSERT' 'OR' 'UPDATE' ) insert_path_pattern ( ',' insert_path_pattern )* insert_path_pattern ::= '(' insert_element_pattern_filler ')' ( insert_edge_pattern '(' insert_element_pattern_filler ')' )* insert_element_pattern_filler ::= (element_variable_declaration? ( ( ('IS' | ':') label_name ( '&' label_name )* ) | ( ( 'TYPED' | '@' ) element_type_name ) ) '{' property_name ':' value_expression ( ',' property_name ':' value_expression )* '}') | element_variable_declaration insert_edge_pattern ::= '<-[' ( insert_element_pattern_filler )? ']-' | '-[' ( insert_element_pattern_filler )? ']->' | '~[' ( insert_element_pattern_filler )? ']~' ```` ## Parameters ### `INSERT | INSERT OR REPLACE | INSERT OR IGNORE | INSERT OR UPDATE` []() When inserting nodes and edges, choose one of the following modes to handle existing data: | Write mode | Behavior | `INSERT` | If the node or edge does not exist, insert it. If it already exists, fail the statement and report an error. | `INSERT OR REPLACE` | If the node or edge does not exist, insert it. If it already exists, replace it with the submitted data. | `INSERT OR IGNORE` | If the node or edge does not exist, insert it. If it already exists, ignore the write and keep the existing data unchanged, without reporting an error. | `INSERT OR UPDATE` | If the node or edge does not exist, insert it. If it already exists, update it with the submitted property values. A node or edge is considered to already exist when its key conflicts with existing data under the following rules: - For nodes of the same node type, the node to be inserted has the same primary key as an existing node. - For edges of the same edge type: - If a multi-edge key is defined, the edge to be inserted has the same multi-edge key, source node, and destination node as an existing edge. - If no multi-edge key is defined, the edge to be inserted has the same source node and destination node as an existing edge. ### `element_variable_declaration` The declaration of an element variable to be bound to a graph element. `element_variable_declaration` is an identifier. For more information about identifiers, see [Rules for naming identifiers](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/overview/keywords-identifiers/). ### `label_name` The name of a label for a graph element. `label_name` is an identifier. For more information about identifiers, see [Rules for naming identifiers](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/overview/keywords-identifiers/). ### `property_name` The name of a property. `property_name` is an identifier. For more information about identifiers, see [Rules for naming identifiers](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/overview/keywords-identifiers/). ### `value_expression` A value or constant that is the value of a property. For more information about the types of value expressions, see [Expressions](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/fe/). ### `element_type_name` The name of a node type or an edge type. `element_type_name` is an identifier. For more information about identifiers, see [Rules for naming identifiers](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/overview/keywords-identifiers/). ## Examples The following examples use the graph `movie` and the graph type `movie_type` created in the example [dataset](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/overview/example-dataset/) to demonstrate how to use the INSERT statement. It assumes that the `movie` graph is set as the current working graph by executing the `SESSION SET GRAPH movie` statement; otherwise, you need to specify the graph name at the beginning of the statement as `USE movie`. For more information, see [USE](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/dql/clauses/use-graph/). ### Insert nodes with node types ```` ''' INSERT (@Director{id:11, name:"Alice", birthDate:date("1990-01-01")}), (TYPED Actor{id:22, name:"Bob", birthDate:date("1990-01-02")}) ''' ```` The preceding statement inserts a node with the node type `Director` and a node with the node type `Actor`. Both the symbol `@` and the keyword `TYPED` are used to specify the node type. ### Insert a conflicting node with `INSERT OR REPLACE` ```` INSERT OR REPLACE (@Director{id:11, name:"Alice2"}) ```` The preceding statement writes a node of type `Director`. If no `Director` node with the primary key `id` set to `11` exists, it inserts the node. Otherwise, it replaces the existing node with the submitted data. To verify the result, you can execute the following statement: ```` MATCH (n@Director{id:11}) RETURN n ```` Return: ```` +------------------------------------------------------------------------+ | n | +------------------------------------------------------------------------+ | (288606709776121860@Director:Person{birthDate:null,id:11,name:Alice2}) | +------------------------------------------------------------------------+ ```` ### Insert nodes and retain existing data with `INSERT OR IGNORE` []() Run this example after the preceding `INSERT OR REPLACE` example. At this point, the graph contains a `Director` node with `id` set to `11`, `name` set to `Alice2`, and `birthDate` set to `NULL`. This example assumes that no `Director` node with `id` set to `12` exists. Submit one node with the same primary key as the existing node and one node that does not yet exist: ```` ''' INSERT OR IGNORE (@Director{id:11, name:"Alice3", birthDate:date("1990-06-30")}), (@Director{id:12, name:"Carol", birthDate:date("1991-01-01")}) ''' ```` - The node with `id` set to `11` already exists: skip this write. Its `name` remains `Alice2`, and its `birthDate` remains `NULL`. - The node with `id` set to `12` does not exist: insert it with `name` set to `Carol` and `birthDate` set to `1991-01-01`. To verify the result, run: ```` ''' MATCH (n@Director) WHERE n.id IN [11, 12] RETURN n.id AS id, n.name AS name, n.birthDate AS birthDate ORDER BY id ''' ```` Return: | id | name | birthDate | 11 | Alice2 | `NULL` | 12 | Carol | 1991-01-01 ### Insert a conflicting node with `INSERT OR UPDATE` ```` INSERT OR UPDATE (@Director{id:11, name:"Alice4", birthDate:date("1990-12-31")}) ```` The preceding statement writes a node of type `Director`. If no `Director` node with the primary key `id` set to `11` exists, it inserts the node. Otherwise, it updates the properties of the existing node. To verify the result, you can execute the following statement: ```` MATCH (n@Director{id:11}) RETURN n ```` Return: ```` +------------------------------------------------------------------------------+ | n | +------------------------------------------------------------------------------+ | (288606709776121860@Director:Person{birthDate:1990-12-31,id:11,name:Alice4}) | +------------------------------------------------------------------------------+ ```` ### Insert nodes with labels ```` ''' INSERT (:Movie{id:10000,name:"movie"}), (IS Genre{id:11000,name:"genre"}) ''' ```` The preceding statement inserts a node with the label `Movie` and a node with the label `Genre`. Both the symbol `:` and the keyword `IS` are used to specify the label. ### Insert a node with NULL ```` INSERT (@Movie{id:10002,name:NULL}) ```` The preceding statement inserts a node with the node type `Movie` and a property `name` with a NULL value. ### Insert an edge based on existing nodes ```` ''' MATCH (n@Movie{id:10000}), (m@User{id:1}) INSERT (n)<-[:Watch{rate:5}]-(m) ''' ```` The preceding statement matches the existing nodes `n` and `m` and inserts an edge from the node `m` to the node `n` with the label `Watch` and a property `rate` with a value of `5`. ### Insert an edge with new nodes ```` INSERT (@Actor{id:200000,name:"actor", birthDate:date("1990-01-01")}) -[@Act]-> (@Movie{id:10003,name:"movie1"}) ```` The preceding statement inserts a node with the node type `Actor` and a node with the node type `Movie`. It then inserts an edge from the node `Actor` to the node `Movie` with the edge type `Act`. ### Insert a node and an edge based on an existing node ```` ''' MATCH (n@Movie{id:10000}) INSERT (n)<-[@Watch{rate:5}]-(@User{id:11002}) ''' ```` The preceding statement matches the existing node `n` and inserts a new node with the node type `User` and an edge from the new node to `n` with the edge type `Watch` and a property `rate` with a value of `5`. ### Insert nodes and edges based on an existing node ```` ''' MATCH (n@User{id:1}) INSERT (n)-[@Watch{rate:5}]->(m@Movie{id:10004,name:"movie2"}), (m)-[@WithGenre]->(@Genre{id:11003,name:"genre3"}) ''' ```` The preceding statement matches the existing node `n` and inserts a new node with the node type `Movie` and an edge from `n` to the new node with the edge type `Watch` and a property `rate` with a value of `5`. It then inserts a new node with the node type `Genre` and an edge from the node `m` to the new node with the edge type `WithGenre`. ### Batch insert nodes and edges with a table variable ```` ''' TABLE t { actor_id, movie_id, movie_name } = ( 2, 20001, 'Movie1' ), ( 3, 20002, 'Movie2' ), ( 4, 20003, 'Movie3' ) USE movie FOR re IN t MATCH (a@Actor) WHERE a.id = re.actor_id INSERT (a)-[@Act]->(@Movie {id: re.movie_id, name: re.movie_name}) ''' ```` The preceding statement defines a table variable `t` and iterates over the table variable to insert data into the graph `movie`. The statement matches nodes of the node type `Actor` based on the field `actor_id` in the table variable and inserts nodes of the node type `Movie` based on fields `movie_id` and `movie_name` in the table variable and also inserts edges between the nodes. For more information about batch operations by using table variables, see [Define table variable](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/variable-definition/table-variable/). ### Insert nodes and edges from a different graph ```` ''' // Create a new graph CREATE GRAPH IF NOT EXISTS another_movie TYPED movie_type ''' ''' USE movie MATCH (a@Actor)-[@Act]->(m@Movie) RETURN a AS actor, m AS movie NEXT USE another_movie INSERT OR REPLACE (@Actor{id:actor.id, name:actor.name, birthDate:actor.birthDate})-[@Act]-> (@Movie{id:movie.id, name:movie.name}) ''' ```` The preceding statements create a new graph `another_movie`, match nodes and edges from the existing graph `movie`, and insert the matched nodes and edges into the new graph `another_movie`.