跳转至

UPSERT EDGE

UPSERT EDGE语句结合UPDATEINSERT,如果边存在,会更新边的属性;如果边不存在,会插入新的边。

UPSERT EDGE性能远低于INSERT,因为UPSERT是一组分片级别的读取、修改、写入操作。

Caution

并发UPSERT同一个 TAG 或 EDGE TYPE 会报错。

语法

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 typeserve的属性start_yearend_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 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可以正常执行,例如:

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子句的条件,就会修改边的属性值。

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     |
+------------+----------+

最后更新: July 6, 2023