UPSERT EDGE¶
UPSERT EDGE语句结合UPDATE和INSERT,如果边存在,会更新边的属性;如果边不存在,会插入新的边。
UPSERT EDGE性能远低于INSERT,因为UPSERT是一组分片级别的读取、修改、写入操作。
Danger
禁止在高并发写操作的情况下使用UPSERT语句,请使用UPDATE或INSERT代替。
语法¶
ngql
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 |
示例如下:
```ngql // 查看如下三个点是否有 serve 类型的出边,结果 “Empty set” 表示没有 serve 类型的出边。 nebula> GO FROM "player666", "player667", "player668" \ OVER serve \ YIELD properties(edge).start_year, properties(edge).end_year; +-----------------------------+---------------------------+ | properties(EDGE).start_year | properties(EDGE).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可以正常执行,例如:
```ngql nebula> CREATE EDGE IF NOT EXISTS 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子句的条件,就会修改边的属性值。
```ngql 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子句的条件,修改不会生效。
```ngql 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 | +------------+----------+ ```