感谢阅读
- 官方文档链接
- NebulaGraph简介
- nGQL
- nGQL简介
- 占位标识符和占位符值¶
- 注释实列
- 大小写区分
- 关键字
- 基本概念以及相关代码实现
- 补充说明
- 图空间语法以及列子
- 创建
- 克隆
- 官方示例代码(创建并克隆)
- USE语句指定图空间时
- 查看所有SPACE
- SPACE详情
- CLEAR SPACE
- 删库跑路(看玩笑的说法)
- 点语法以及列子
- 插入点
- 官方示例代码(重复插入同一个)
- 删除点
- 官方删除点的两种示例
- 更新点
- 官方示例代码
- 更新插入操作
- 如果点存在,且满足WHEN子句的条件,就会修改点的属性值。(官方示例)
- Tag语法以及列子
- 创建标签
- 官方代码(创建标签)
- 删除当前工作空间内所有点上的指定标签
- 修改标签属性
- 显示当前图空间内的所有 Tag 名称
- 显示指定 Tag 的详细信息
- 删除指定点上的指定 Tag
- 增加和删除标签
- 官方代码(增加删除标签的常用用法)
- 边以及边类型语法以及列子(官方和论文是分开的,但我认为连一起合理)
- 创建边
- 删除当前工作空间内的指定 Edge type
- 修改 Edge type 的结构
- 官方代码(修改边)
- 展示全部边
- Edge type 的详细信息
- 插入边
- 官方示例代码
- 删除边
- 如果不指定 rank,则仅仅删除 rank 为 0 的边。需要删除所有的 rank,见如下示例。
- 官方代码(管道删除)
- 修改边上 Edge type 的属性
- 官方更新点代码
- UPSERT EDGE
- 路径
官方文档链接
点我跳转
本文结合国内外论文和官方链接,根据自己的理解进行整理和排序。
NebulaGraph简介
NebulaGraph 是一款开源的、分布式的、易扩展的原生图数据库,能够承载包含数千亿个点和数万亿条边的超大规模数据集,并且提供毫秒级查询。
nGQL
nGQL简介
nGQL是 NebulaGraph 使用的的声明式图查询语言,支持灵活高效的图模式,而且 nGQL 是为开发和运维人员设计的类 SQL 查询语言,易于学习。
占位标识符和占位符值¶
NebulaGraph 查询语言 nGQL 参照以下标准设计:
(Draft) ISO/IEC JTC1 N14279 SC 32 - Database_Languages - GQL
(Draft) ISO/IEC JTC1 SC32 N3228 - SQL_Property_Graph_Queries - SQLPGQ
OpenCypher 9
在模板代码中,任何非关键字、字面值或标点符号的标记都是占位符标识符或占位符值。
注释实列
nebula> RETURN 1+1; # 这条注释延续到行尾。
nebula> RETURN 1+1; // 这条注释延续到行尾。
nebula> RETURN 1 /* 这是一条行内注释 */ + 1 == 2;
nebula> RETURN 11 + \
/* 多行注释 \
用反斜线来换行。 \
*/ 12;
openCypher 兼容性¶
在 nGQL 中,用户必须在行末使用反斜线(\)来换行,即使是在使用/* */符号的多行注释内。
在 openCypher 中不需要使用反斜线换行。
/* openCypher 风格:
这条注释
延续了不止
一行 */
MATCH (n:label)
RETURN n;
/* 原生 nGQL 风格: \
这条注释 \
延续了不止 \
一行 */ \
MATCH (n:tag) \
RETURN n;
大小写区分
标识符区分大小写
关键字不区分大小写
函数不区分大小写
关键字
关键字是 nGQL 中具有特殊含义的词,例如CREATE TAG语句中的CREATE和TAG。需要经过特殊处理才能作为标识符使用的关键字被称为保留关键字,而能够直接作为标识符使用的这部分关键字被称为非保留关键字。
不建议在创建 Schema 时使用关键字。如果必须使用关键字需要遵循一定规则(为了防止意外,不介绍了)
基本概念以及相关代码实现
图(Graph):
图是由节点和边组成的数据结构,用于展示实体之间的关系。图可以划分为多个子图(Graph Space),每个子图都包含一组相关的节点和边。每个子图都可以有不同的模式、数据和配置。
点(Vertex):
点代表图中的实体,可以带有各种属性。在 Nebula 中,每个点都有一个唯一的标识符,称为 Vertex ID。点用于表达现实世界中的实体。
标签(Tag):
标签是一组相同类型的点的集合,用于对点进行分类或分组。每个标签都有一个名称,点可以分配给一个或多个标签。标签在数据模型中提供更好的组织和查询能力。
边(Edge):
边表示图中的关联,将两个点连接起来。每个边都有一个起始节点和一个结束节点,以及一个唯一的标识符,称为 Edge ID。边用于描述实体之间的联系。
边类型(Edge Type):
边类型用于区分不同类型的边。每条边都属于一个类型,类型可用于定义边的含义和语义。例如,可以使用不同类型来表示不同种类的关系。
属性(Property):
属性是与点和边相关的数据。每个点和边都可以拥有零个或多个属性,用于描述它们的特征、信息或状态。例如,人的点可以有姓名、年龄、性别等属性。
补充说明
1.Tag 和 Edge type 的作用,类似于关系型数据库中“点表”和“边表”的表结构。
2.Rank 可以用来区分 Edge type、起始点、目的点都相同的边。该值完全由用户自己指定。读取时必须自行取得全部的 Rank 值后排序过滤和拼接。不支持诸如next(), pre(), head(), tail(), max(), min(), lessThan(), moreThan()等函数功能,也不能通过创建索引加速访问或者条件过滤。
3.NebulaGraph 中没有无向边,只支持有向边。
4.NebulaGraph 3.6.0 的数据模型中,允许存在"悬挂边",因此在增删时,用户需自行保证“一条边所对应的起点和终点”的存在性。
5.不支持 openCypher 中的 MERGE 语句。
图空间语法以及列子
图空间是 NebulaGraph 中彼此隔离的图数据集合,与 MySQL 中的 database 概念类似。CREATE SPACE语句可以创建一个新的图空间,或者克隆现有图空间的 Schema。
创建
只有 God 角色的用户可以执行CREATE SPACE语句
CREATE SPACE [IF NOT EXISTS] <graph_space_name> ([partition_num = <partition_number>,][replica_factor = <replica_number>,]vid_type = {FIXED_STRING(<N>) | INT[64]})[COMMENT = '<comment>'];
2.5.0 之前的 2.x 版本中,vid_type不是必选参数,默认为FIXED_STRING(8)。
克隆
CREATE SPACE [IF NOT EXISTS] <new_graph_space_name> AS <old_graph_space_name>;
官方示例代码(创建并克隆)
# 仅指定 VID 类型,其他选项使用默认值。
nebula> CREATE SPACE IF NOT EXISTS my_space_1 (vid_type=FIXED_STRING(30));# 指定分片数量、副本数量和 VID 类型。
nebula> CREATE SPACE IF NOT EXISTS my_space_2 (partition_num=15, replica_factor=1, vid_type=FIXED_STRING(30));# 指定分片数量、副本数量和 VID 类型,并添加描述。
nebula> CREATE SPACE IF NOT EXISTS my_space_3 (partition_num=15, replica_factor=1, vid_type=FIXED_STRING(30)) comment="测试图空间";# 克隆图空间。
nebula> CREATE SPACE IF NOT EXISTS my_space_4 as my_space_3;
nebula> SHOW CREATE SPACE my_space_4;
+--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Space | Create Space |
+--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| "my_space_4" | "CREATE SPACE `my_space_4` (partition_num = 15, replica_factor = 1, charset = utf8, collate = utf8_bin, vid_type = FIXED_STRING(30)) comment = '测试图空间'" |
+--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
USE语句指定图空间时
USE <graph_space_name>;
执行USE语句指定图空间时,需要当前登录的用户拥有指定图空间的权限,否则会报错。
查看所有SPACE
SHOW SPACES语句可以列出 NebulaGraph 示例中的所有图空间。
SPACE详情
DESCRIBE SPACE语句可以显示指定图空间的信息。
CLEAR SPACE
CLEAR SPACE语句用于清空图空间中的点和边,但不会删除图空间本身以及其中的 Schema 信息。只有 God 角色的用户可以执行CLEAR SPACE语句。
CLEAR SPACE [IF EXISTS] <space_name>;
注意事项¶
数据清除后,如无备份,无法恢复。使用该功能务必谨慎。
CLEAR SPACE不是原子性操作。如果执行出错,请重新执行,避免残留数据。
图空间中的数据量越大,CLEAR SPACE消耗的时间越长。如果CLEAR SPACE的执行因客户端连接超时而失败,可以增大 Graph 服务配置中storage_client_timeout_ms参数的值。
在CLEAR SPACE的执行过程中,向该图空间写入数据的行为不会被自动禁止。这样的写入行为可能导致CLEAR SPACE清除数据不完全,残留的数据也可能受到损坏。
图空间中,CLEAR SPACE不会删除的数据包括:
Tag 信息。
Edge type 信息。
原生索引和全文索引的元数据。
删库跑路(看玩笑的说法)
DROP SPACE语句用于删除指定图空间以及其中的所有信息。只有 God 角色的用户可以执行DROP SPACE语句。
DROP SPACE [IF EXISTS] <graph_space_name>;
点语法以及列子
插入点
执行INSERT VERTEX语句需要当前登录的用户拥有指定图空间的插入点权限,否则会报错。
INSERT VERTEX [IF NOT EXISTS] [tag_props, [tag_props] ...]
VALUES VID: ([prop_value_list])tag_props:tag_name ([prop_name_list])prop_name_list:[prop_name [, prop_name] ...]prop_value_list:[prop_value [, prop_value] ...]
参数解释:
IF NOT EXISTS:检测待插入的 VID 是否存在,只有不存在时,才会插入,如果已经存在,不会进行修改。NoteIF NOT EXISTS 仅检测 VID + Tag 的值是否相同,不会检测属性值。
IF NOT EXISTS 会先读取一次数据是否存在,因此对性能会有明显影响。
tag_name:点关联的 Tag(点类型)。Tag 的创建,详情请参见 CREATE TAG。CautionNebulaGraph 3.6.0 中默认不支持插入无 Tag 的点。如需使用无 Tag 的点,在集群内所有 Graph 服务的配置文件(nebula-graphd.conf)中新增--graph_use_vertex_key=true;在所有 Storage 服务的配置文件(nebula-storaged.conf)中新增--use_vertex_key=true。插入无 Tag 点的命令示例如INSERT VERTEX VALUES "1":();。property_name:需要设置的属性名称。
vid:点 ID。在 NebulaGraph 3.6.0 中支持字符串和整数,需要在创建图空间时设置,详情请参见 CREATE SPACE。
property_value:根据prop_name_list填写属性值。如果没有填写属性值,而 Tag 中对应的属性设置为NOT NULL,会返回错误。
官方示例代码(重复插入同一个)
# 多次插入属性值。
nebula> INSERT VERTEX t2 (name, age) VALUES "11":("n2", 13);
nebula> INSERT VERTEX t2 (name, age) VALUES "11":("n3", 14);
nebula> INSERT VERTEX t2 (name, age) VALUES "11":("n4", 15);
nebula> FETCH PROP ON t2 "11" YIELD properties(vertex);
+-----------------------+
| properties(VERTEX) |
+-----------------------+
| {age: 15, name: "n4"} |
+-----------------------+
删除点
DELETE VERTEX语句可以删除点,但是默认不删除该点关联的出边和入边。
DELETE VERTEX <vid> [ , <vid> ... ] [WITH EDGE];
WITH EDGE: 删除该点关联的出边和入边。
官方删除点的两种示例
# 删除 VID 为 `team1` 的点,不删除该点关联的出边和入边。
nebula> DELETE VERTEX "team1";# 删除 VID 为 `team1` 的点,并删除该点关联的出边和入边。
nebula> DELETE VERTEX "team1" WITH EDGE;
# 结合管道符,删除符合条件的点。
nebula> GO FROM "player100" OVER serve WHERE properties(edge).start_year == "2021" YIELD dst(edge) AS id | DELETE VERTEX $-.id;
更新点
一次只能修改一个 Tag。UPDATE VERTEX语句可以修改点上 Tag 的属性值。
UPDATE VERTEX ON <tag_name> <vid>
SET <update_prop>
[WHEN <condition>]
[YIELD <output>]
官方示例代码
// 查看点”player101“的属性。
nebula> FETCH PROP ON player "player101" YIELD properties(vertex);
+--------------------------------+
| properties(VERTEX) |
+--------------------------------+
| {age: 36, name: "Tony Parker"} |
+--------------------------------+// 修改属性 age 的值,并返回 name 和新的 age。
nebula> UPDATE VERTEX ON player "player101" \SET age = age + 2 \WHEN name == "Tony Parker" \YIELD name AS Name, age AS Age;
+---------------+-----+
| Name | Age |
+---------------+-----+
| "Tony Parker" | 38 |
+---------------+-----+
更新插入操作
UPSERT VERTEX语句结合UPDATE和INSERT,如果点存在,会修改点的属性值;如果点不存在,会插入新的点。UPSERT VERTEX一次只能修改一个 Tag。
UPSERT VERTEX性能远低于INSERT,因为UPSERT是一组分片级别的读取、修改、写入操作。
如果点存在,且满足WHEN子句的条件,就会修改点的属性值。(官方示例)
nebula> FETCH PROP ON player "player101" YIELD properties(vertex);
+--------------------------------+
| properties(VERTEX) |
+--------------------------------+
| {age: 36, name: "Tony Parker"} |
+--------------------------------+nebula> UPSERT VERTEX ON player "player101" \SET age = age + 2 \WHEN name == "Tony Parker" \YIELD name AS Name, age AS Age;
+---------------+-----+
| Name | Age |
+---------------+-----+
| "Tony Parker" | 38 |
+---------------+-----+
Tag语法以及列子
创建标签
CREATE TAG语句可以通过指定名称创建一个 Tag。执行CREATE TAG语句需要当前登录的用户拥有指定图空间的创建 Tag 权限,否则会报错。创建 Tag 前,需要先用USE语句指定工作空间。
openCypher 中的 Label 需要在CREATE语句中与点一起创建。
nGQL 中的 Tag 需要使用CREATE TAG语句独立创建。Tag 更像是 MySQL 中的表。
CREATE TAG [IF NOT EXISTS] <tag_name>(<prop_name> <data_type> [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>'][{, <prop_name> <data_type> [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>']} ...] )[TTL_DURATION = <ttl_duration>][TTL_COL = <prop_name>][COMMENT = '<comment>'];
官方代码(创建标签)
nebula> CREATE TAG IF NOT EXISTS player(name string, age int);# 创建没有属性的 Tag。
nebula> CREATE TAG IF NOT EXISTS no_property(); # 创建包含默认值的 Tag。
nebula> CREATE TAG IF NOT EXISTS player_with_default(name string, age int DEFAULT 20);# 对字段 create_time 设置 TTL 为 100 秒。
nebula> CREATE TAG IF NOT EXISTS woman(name string, age int, \married bool, salary double, create_time timestamp) \TTL_DURATION = 100, TTL_COL = "create_time";
删除当前工作空间内所有点上的指定标签
点可以有一个或多个 Tag。
如果某个点只有一个 Tag,删除这个 Tag 后,用户就无法访问这个点,下次 Compaction 操作时会删除该点,但与该点相邻的边仍然存在——这会造成悬挂边。
如果某个点有多个 Tag,删除其中一个 Tag,仍然可以访问这个点,但是无法访问已删除 Tag 所定义的所有属性。
删除 Tag 操作仅删除 Schema 数据,硬盘上的文件或目录不会立刻删除,而是在下一次 Compaction 操作时删除。
确保要修改的属性不包含索引,否则ALTER TAG时会报冲突错误[ERROR (-1005)]: Conflict!。(根据我的理解,这里的修改属性操作包括索引)
确保新增的属性名不与已存在或被删除的属性名同名,否则新增属性会失败。
DROP TAG [IF EXISTS] <tag_name>;
修改标签属性
ALTER TAG语句可以修改 Tag 的结构。例如增删属性、修改数据类型,也可以为属性设置、修改 TTL(Time-To-Live)
ALTER TAG <tag_name><alter_definition> [[, alter_definition] ...][ttl_definition [, ttl_definition] ... ][COMMENT = '<comment>'];alter_definition:
| ADD (prop_name data_type [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>'])
| DROP (prop_name)
| CHANGE (prop_name data_type [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>'])ttl_definition:TTL_DURATION = ttl_duration, TTL_COL = prop_name
官方示例代码
nebula> CREATE TAG IF NOT EXISTS t1 (p1 string, p2 int);
nebula> ALTER TAG t1 ADD (p3 int32, p4 fixed_string(10));
nebula> ALTER TAG t1 TTL_DURATION = 2, TTL_COL = "p2";
nebula> ALTER TAG t1 COMMENT = 'test1';
nebula> ALTER TAG t1 ADD (p5 double NOT NULL DEFAULT 0.4 COMMENT 'p5') COMMENT='test2';
// 将 TAG t1 的 p3 属性类型从 INT32 改为 INT64,p4 属性类型从 FIXED_STRING(10) 改为 STRING。
nebula> ALTER TAG t1 CHANGE (p3 int64, p4 string);
显示当前图空间内的所有 Tag 名称
SHOW TAGS;
显示指定 Tag 的详细信息
DESC[RIBE] TAG <tag_name>;
删除指定点上的指定 Tag
DELETE TAG <tag_name_list> FROM <VID_list>;
tag_name_list:指定 Tag 名称。多个 Tag 用英文逗号(,)分隔,也可以用*表示所有 Tag。
VID_list:指定要删除 Tag 的点 ID。可以指定多个 VID,用英文逗号(,)分隔。
增加和删除标签
在 openCypher 中,有增加标签(SET label)和移除标签(REMOVE label)的功能,可以用于加速查询或者标记过程。
在 NebulaGraph 中,可以通过 Tag 变相实现相同操作,创建 Tag 并将 Tag 插入到已有的点上,就可以根据 Tag 名称快速查找点,也可以通过DELETE TAG删除某些点上不再需要的 Tag。
官方代码(增加删除标签的常用用法)
//创建股东 Tag 和索引
nebula> CREATE TAG IF NOT EXISTS shareholder();
nebula> CREATE TAG INDEX IF NOT EXISTS shareholder_tag on shareholder();//为点添加 Tag
nebula> INSERT VERTEX shareholder() VALUES "player100":();
nebula> INSERT VERTEX shareholder() VALUES "player101":();//快速查询所有股东
nebula> MATCH (v:shareholder) RETURN v;
+---------------------------------------------------------------------+
| v |
+---------------------------------------------------------------------+
| ("player100" :player{age: 42, name: "Tim Duncan"} :shareholder{}) |
| ("player101" :player{age: 36, name: "Tony Parker"} :shareholder{}) |
+---------------------------------------------------------------------+
nebula> LOOKUP ON shareholder YIELD id(vertex);
+-------------+
| id(VERTEX) |
+-------------+
| "player100" |
| "player101" |
+-------------+//如果 player100 不再是股东
nebula> DELETE TAG shareholder FROM "player100";
nebula> LOOKUP ON shareholder YIELD id(vertex);
+-------------+
| id(VERTEX) |
+-------------+
| "player101" |
+-------------+
边以及边类型语法以及列子(官方和论文是分开的,但我认为连一起合理)
创建边
CREATE EDGE语句可以通过指定名称创建一个 Edge type。
OpenCypher 兼容性¶
nGQL 中的 Edge type 和 openCypher 中的关系类型相似,但又有所不同,例如它们的创建方式。
openCypher 中的关系类型需要在CREATE语句中与点一起创建。
nGQL 中的 Edge type 需要使用CREATE EDGE语句独立创建。Edge type 更像是 MySQL 中的表。
CREATE EDGE [IF NOT EXISTS] <edge_type_name>(<prop_name> <data_type> [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>'][{, <prop_name> <data_type> [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>']} ...] )[TTL_DURATION = <ttl_duration>][TTL_COL = <prop_name>][COMMENT = '<comment>'];
删除当前工作空间内的指定 Edge type
DROP EDGE [IF EXISTS] <edge_type_name>
修改 Edge type 的结构
ALTER EDGE语句可以修改 Edge type 的结构。例如增删属性、修改数据类型,也可以为属性设置、修改 TTL(Time-To-Live)。
注意事项¶
登录的用户必须拥有对应权限才能执行ALTER EDGE语句。详情请参见内置角色权限。
确保要修改的属性不包含索引,否则ALTER EDGE时会报冲突错误[ERROR (-1005)]: Conflict!。
确保新增的属性名不与已存在或被删除的属性名同名,否则新增属性会失败。
允许增加FIXED_STRING和INT类型的长度。
允许FIXED_STRING类型转换为STRING类型、FLOAT类型转换为DOUBLE类型。
ALTER EDGE <edge_type_name><alter_definition> [, alter_definition] ...][ttl_definition [, ttl_definition] ... ][COMMENT = '<comment>'];alter_definition:
| ADD (prop_name data_type)
| DROP (prop_name)
| CHANGE (prop_name data_type)ttl_definition:TTL_DURATION = ttl_duration, TTL_COL = prop_name
edge_type_name:指定要修改的 Edge type 名称。一次只能修改一个 Edge type。请确保要修改的 Edge type 在当前工作空间中存在,否则会报错。
可以在一个ALTER EDGE语句中使用多个ADD、DROP和CHANGE子句,子句之间用英文逗号(,)分隔。
当使用ADD或CHANGE指定属性值为NOT NULL时,必需为该属性指定默认值,即定义DEFAULT的值。
官方代码(修改边)
nebula> CREATE EDGE IF NOT EXISTS e1(p1 string, p2 int);
nebula> ALTER EDGE e1 ADD (p3 int, p4 string);
nebula> ALTER EDGE e1 TTL_DURATION = 2, TTL_COL = "p2";
nebula> ALTER EDGE e1 COMMENT = 'edge1';
展示全部边
SHOW EDGES;
Edge type 的详细信息
DESC[RIBE] EDGE <edge_type_name>
插入边
INSERT EDGE语句可以在 NebulaGraph 实例的指定图空间中插入一条或多条边。边是有方向的,从起始点(src_vid)到目的点(dst_vid)。
INSERT EDGE的执行方式为覆盖式插入。如果已有 Edge type、起点、终点、rank 都相同的边,则覆盖原边。
INSERT EDGE [IF NOT EXISTS] <edge_type> ( <prop_name_list> ) VALUES
<src_vid> -> <dst_vid>[@<rank>] : ( <prop_value_list> )
[, <src_vid> -> <dst_vid>[@<rank>] : ( <prop_value_list> ), ...];<prop_name_list> ::=[ <prop_name> [, <prop_name> ] ...]<prop_value_list> ::=[ <prop_value> [, <prop_value> ] ...]
官方示例代码
nebula> CREATE EDGE IF NOT EXISTS e2 (name string, age int);
nebula> INSERT EDGE e2 (name, age) VALUES "11"->"13":("n1", 1);# 一次插入 2 条边。
nebula> INSERT EDGE e2 (name, age) VALUES \"12"->"13":("n1", 1), "13"->"14":("n2", 2); # 创建失败,因为"a13"不是 int 类型。
nebula> INSERT EDGE e2 (name, age) VALUES "11"->"13":("n1", "a13");
删除边
DELETE EDGE <edge_type> <src_vid> -> <dst_vid>[@<rank>] [, <src_vid> -> <dst_vid>[@<rank>] ...]
如果不指定 rank,则仅仅删除 rank 为 0 的边。需要删除所有的 rank,见如下示例。
nebula> DELETE EDGE serve "player100" -> "team204"@0;
官方代码(管道删除)
# 结合管道符,删除两点之间同类型的所有rank的边。
nebula> GO FROM "player100" OVER follow \WHERE dst(edge) == "player101" \YIELD src(edge) AS src, dst(edge) AS dst, rank(edge) AS rank \| DELETE EDGE follow $-.src -> $-.dst @ $-.rank;
修改边上 Edge type 的属性
UPDATE EDGE ON <edge_type>
<src_vid> -> <dst_vid> [@<rank>]
SET <update_prop>
[WHEN <condition>]
[YIELD <output>]
官方更新点代码
// 用 GO 语句查看边的属性值。
nebula> GO FROM "player100" \OVER serve \YIELD properties(edge).start_year, properties(edge).end_year;
+-----------------------------+---------------------------+
| properties(EDGE).start_year | properties(EDGE).end_year |
+-----------------------------+---------------------------+
| 1997 | 2016 |
+-----------------------------+---------------------------+// 修改属性 start_year 的值,并返回 end_year 和新的 start_year。nebula> UPDATE EDGE ON serve "player100" -> "team204"@0 \SET start_year = start_year + 1 \WHEN end_year > 2010 \YIELD start_year, end_year;
+------------+----------+
| start_year | end_year |
+------------+----------+
| 1998 | 2016 |
+------------+----------+
UPSERT EDGE
UPSERT EDGE语句结合UPDATE和INSERT,如果边存在,会更新边的属性;如果边不存在,会插入新的边。UPSERT EDGE性能远低于INSERT,因为UPSERT是一组分片级别的读取、修改、写入操作。并发UPSERT同一个 TAG 或 EDGE TYPE 会报错。
UPSERT EDGE ON <edge_type>
<src_vid> -> <dst_vid> [@rank]
SET <update_prop>
[WHEN <condition>]
[YIELD <properties>]