UPSERT EDGE
UPSERT EDGE
语句结合UPDATE
和INSERT
,如果边存在,会更新边的属性;如果边不存在,会插入新的边。
UPSERT EDGE
性能远低于INSERT
,因为UPSERT
是一组分片级别的读取、修改、写入操作。
语法
UPSERT EDGE ON <edge_type>
<src_vid> -> <dst_vid> [@rank]
SET <update_prop>
[WHEN <condition>]
[YIELD <properties>]
参数 | 是否必须 | 说明 | 示例 |
---|---|---|---|
ON <edge_type> | 是 | 指定Edge type。要修改的属性必须在这个Edge type内。 | ON serve |
<src_vid> | 是 | 指定边的起始点ID。 | “player100” |
<dst_vid> | 是 | 指定边的目的点ID。 | “team204” |
<rank> | 否 | 指定边的rank值。 | 10 |
SET <update_prop> | 是 | 指定如何修改属性值。 | SET start_year = start_year +1 |
WHEN <condition> | 否 | 指定过滤条件。 | WHEN end_year < 2010 |
YIELD <output> | 否 | 指定语句的输出格式。 | YIELD start_year AS Start_Year |
插入不存在的边
如果边不存在,无论WHEN
子句的条件是否满足,都会插入边,同时执行SET
子句,因此新插入的边的属性值取决于:
SET
子句。属性是否有默认值。
例如:
要插入的边包含基于Edge type
serve
的属性start_year
和end_year
。SET
子句指定end_year = 2021
。
不同情况下的属性值如下表。
是否满足WHEN 子句条件 | 属性是否有默认值 | start_year 属性值 | end_year 属性值 |
---|---|---|---|
是 | 是 | 默认值 | 2021 |
是 | 否 | NULL | 2021 |
否 | 是 | 默认值 | 2021 |
否 | 否 | NULL | 2021 |
示例如下:
// 查看如下三个点是否有serve类型的出边,结果“Empty set”表示没有serve类型的出边。
nebula> GO FROM "player666", "player667", "player668" \
OVER serve \
YIELD serve.start_year, serve.end_year;
Empty set
nebula> UPSERT EDGE on serve \
"player666" -> "team200"@0 \
SET end_year = 2021 \
WHEN end_year == 2010 \
YIELD start_year, end_year;
+------------+----------+
| start_year | end_year |
+------------+----------+
| __NULL__ | 2021 |
+------------+----------+
nebula> UPSERT EDGE on serve \
"player666" -> "team200"@0 \
SET end_year = 2022 \
WHEN end_year == 2010 \
YIELD start_year, end_year;
+------------+----------+
| start_year | end_year |
+------------+----------+
| __NULL__ | 2021 |
+------------+----------+
nebula> UPSERT EDGE on serve \
"player667" -> "team200"@0 \
SET end_year = 2022 \
YIELD start_year, end_year;
+------------+----------+
| start_year | end_year |
+------------+----------+
| __NULL__ | 2022 |
+------------+----------+
nebula> UPSERT EDGE on serve \
"player668" -> "team200"@0 \
SET start_year = 2000, end_year = end_year + 1 \
YIELD start_year, end_year;
+------------+----------+
| start_year | end_year |
+------------+----------+
| 2000 | __NULL__ |
+------------+----------+
上面最后一个示例中,因为end_year
没有默认值,插入边时,end_year
默认值为NULL
,执行end_year = end_year + 1
后仍为NULL
。如果end_year
有默认值,则end_year = end_year + 1
可以正常执行,例如:
nebula> CREATE EDGE serve_with_default(start_year int, end_year int DEFAULT 2010);
Execution succeeded
nebula> UPSERT EDGE on serve_with_default \
"player668" -> "team200" \
SET end_year = end_year + 1 \
YIELD start_year, end_year;
+------------+----------+
| start_year | end_year |
+------------+----------+
| __NULL__ | 2011 |
+------------+----------+
修改存在的边
如果边存在,且满足WHEN
子句的条件,就会修改边的属性值。
nebula> MATCH (v:player{name:"Ben Simmons"})-[e:serve]-(v2) \
RETURN e;
+-----------------------------------------------------------------------+
| e |
+-----------------------------------------------------------------------+
| [:serve "player149"->"team219" @0 {end_year: 2019, start_year: 2016}] |
+-----------------------------------------------------------------------+
nebula> UPSERT EDGE on serve \
"player149" -> "team219" \
SET end_year = end_year + 1 \
WHEN start_year == 2016 \
YIELD start_year, end_year;
+------------+----------+
| start_year | end_year |
+------------+----------+
| 2016 | 2020 |
+------------+----------+
如果边存在,但是不满足WHEN
子句的条件,修改不会生效。
nebula> MATCH (v:player{name:"Ben Simmons"})-[e:serve]-(v2) \
RETURN e;
+-----------------------------------------------------------------------+
| e |
+-----------------------------------------------------------------------+
| [:serve "player149"->"team219" @0 {end_year: 2020, start_year: 2016}] |
+-----------------------------------------------------------------------+
nebula> UPSERT EDGE on serve \
"player149" -> "team219" \
SET end_year = end_year + 1 \
WHEN start_year != 2016 \
YIELD start_year, end_year;
+------------+----------+
| start_year | end_year |
+------------+----------+
| 2016 | 2020 |
+------------+----------+