INSERT¶
INSERT语句用于往图或临时图中插入点和边。
Note
对非默认 Schema 或其中的对象执行操作时,用户既要通过隐式访问规则或显式USAGE授权获得该 Schema 的访问权,也要具备目标操作所需的权限。Schema 访问校验和目标操作所需的权限校验相互独立,满足其中一项不能替代另一项。Schema 访问控制不适用于临时图、内置 Procedure 和内置 Function。更多信息,请参见 Schema 访问控制。
前提条件¶
- 已创建图或临时图。更多信息,请参见 CREATE GRAPH 和 CREATE TEMPORARY GRAPH。
- 若要往图中插入点和边,须具备在当前 Schema 执行
INSERT ANY GRAPH操作的权限,或具备在当前图中执行INSERT操作的权限。更多信息,请参见角色与权限。 - 若要往临时图中插入点和边,必须是具备角色
ADMIN的用户或临时图的所有者。
语法¶
- 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 )? ']~'
参数¶
INSERT | INSERT OR REPLACE | INSERT OR IGNORE | INSERT OR UPDATE ¶
插入点和边时,可以选择以下模式处理已存在的数据:
| 写入模式 | 行为 |
|---|---|
INSERT |
数据不存在时插入;已存在时,语句执行失败并报告错误。 |
INSERT OR REPLACE |
数据不存在时插入;已存在时,用本次提交的数据替换原有点或边。 |
INSERT OR IGNORE |
数据不存在时插入;已存在时,忽略本次写入,保留原有数据,不报错。 |
INSERT OR UPDATE |
数据不存在时插入;已存在时,用本次提交的属性值更新原有点或边。 |
数据是否已存在,按以下键冲突规则判断:
- 对于相同点类型的点,待插入点的主键与已有点的主键相同。
- 对于相同边类型的边:
- 若定义过多边键,待插入边的多边键、起始点和目标点与已有边的多边键、起始点和目标点均相同。
- 若未定义多边键,待插入边的起始点和目标点与已有边的起始点和目标点相同。
element_variable_declaration¶
声明图元素点或边的变量,以便引用和操作这些图元素。该变量为一个标识符。更多信息,请参见标识符命名规则。
label_name¶
图元素点或边的标签名称。该名称为一个标识符。更多信息,请参见标识符命名规则。
property_name¶
属性的名称。该名称为一个标识符。更多信息,请参见标识符命名规则。
value_expression¶
属性的值。更多信息,请参见值表达式。
element_type_name¶
点类型或边类型的名称。该名称为一个标识符。更多信息,请参见标识符命名规则。
示例¶
以下示例基于示例数据集中的创建的图movie和图类型movie_type,展示如何使用INSERT语句。
在执行以下示例语句前,假设您已执行SESSION SET GRAPH movie语句将图movie设置为当前工作图;否则,需要在语句的开头指定图名称,如USE movie。更多信息,请参见 USE。
指定点类型插入点¶
'''
INSERT (@Director{id:11, name:"Alice", birthDate:date("1990-01-01")}),
(TYPED Actor{id:22, name:"Bob", birthDate:date("1990-01-02")})
'''
上述语句插入了一个点类型为Director的点和一个点类型为Actor的点。符号@和关键字TYPED都可用于指定点类型。
通过INSERT OR REPLACE插入有冲突的点¶
INSERT OR REPLACE (@Director{id:11, name:"Alice2"})
上述语句写入一个点类型为Director的点。如果图中不存在主键id为11的Director点,则插入;如果已存在,则用本次提交的数据替换已有点。
执行以下语句验证插入结果:
MATCH (n@Director{id:11}) RETURN n
返回:
+------------------------------------------------------------------------+
| n |
+------------------------------------------------------------------------+
| (288606709776121860@Director:Person{birthDate:null,id:11,name:Alice2}) |
+------------------------------------------------------------------------+
通过INSERT OR IGNORE插入点并保留已有数据¶
本例接着上一个INSERT OR REPLACE示例执行。此时,图中已存在id为11的Director点,其name为Alice2、birthDate为NULL。假设图中尚不存在id为12的Director点。
执行以下语句,分别提交一个与已有点主键相同的点和一个尚不存在的点:
'''
INSERT OR IGNORE (@Director{id:11, name:"Alice3", birthDate:date("1990-06-30")}),
(@Director{id:12, name:"Carol", birthDate:date("1991-01-01")})
'''
id为11的点已存在:跳过该点的本次写入,name仍为Alice2,birthDate仍为NULL。id为12的点不存在:正常插入,name为Carol,birthDate为1991-01-01。
执行以下语句验证结果:
'''
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
'''
返回:
| id | name | birthDate |
|---|---|---|
| 11 | Alice2 | NULL |
| 12 | Carol | 1991-01-01 |
通过INSERT OR UPDATE插入有冲突的点¶
INSERT OR UPDATE (@Director{id:11, name:"Alice4", birthDate:date("1990-12-31")})
上述语句写入一个点类型为Director的点。如果图中不存在主键id为11的Director点,则插入;如果已存在,则更新已有点的属性。
执行以下语句验证插入结果:
MATCH (n@Director{id:11}) RETURN n
返回:
+------------------------------------------------------------------------------+
| n |
+------------------------------------------------------------------------------+
| (288606709776121860@Director:Person{birthDate:1990-12-31,id:11,name:Alice4}) |
+------------------------------------------------------------------------------+
指定标签插入点¶
'''
INSERT (:Movie{id:10000,name:"movie"}),
(IS Genre{id:11000,name:"genre"})
'''
上述语句插入了一个标签为Movie的点和一个标签为Genre的点。符号:和关键字IS都可用于指定标签。
插入具有 NULL 值的点¶
INSERT (@Movie{id:10002,name:NULL})
上述语句插入了一个点类型为Movie的点,并且属性name的值为NULL。
基于已存在的点插入边¶
'''
MATCH (n@Movie{id:10000}), (m@User{id:1})
INSERT (n)<-[:Watch{rate:5}]-(m)
'''
上述语句匹配已存在的点n和m,并插入一条从点m到点n的边,边的标签为Watch,并且边的属性rate的值为5。
同时插入新的点和边¶
'''
INSERT (@Actor{id:200000,name:"actor", birthDate:date("1990-01-01")}) -[@Act]-> (@Movie{id:10003,name:"movie1"})
'''
上述语句插入一个点类型为Actor的点和一个点类型为Movie的点,然后插入一条从点Actor到点Movie的边,边的类型为Act。
基于已存在的点插入点和边¶
'''
MATCH (n@Movie{id:10000})
INSERT (n)<-[@Watch{rate:5}]-(@User{id:11002})
'''
上述语句匹配已存在点n,并插入一个新点,点类型为User,以及一条从新点到n的边,边的类型为Watch,并且边的属性rate的值为5。
基于已存在的点插入多个点和边¶
'''
MATCH (n@User{id:1})
INSERT (n)-[@Watch{rate:5}]->(m@Movie{id:10004,name:"movie2"}),
(m)-[@WithGenre]->(@Genre{id:11003,name:"genre3"})
'''
上述语句匹配已存在的点n,插入一个新点,点类型为Movie,以及一条从n到新点的边,边的类型为Watch,并且边的属性rate的值为5。然后再插入一个新点,点类型为Genre,以及一条从点m到新点的边,边的类型为WithGenre。
使用表变量批量插入点和边¶
'''
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})
'''
上述语句定义了表变量t,并遍历表变量将数据插入到图movie中。该语句基于表变量的字段actor_id匹配点类型为Actor的点,并基于字段movie_id和movie_name的值插入点类型为Movie的点,并在这些点之间插入边。
关于使用表变量进行批量操作的更多信息,请参见定义表变量。
跨图插入点和边¶
'''
// 创建新图
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})
'''
上述语句创建了一个新图another_movie,从已存在的图movie中匹配点和边,并将匹配到的点和边插入到新图another_movie中。