UPSERT EDGE

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

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

语法

  1. UPSERT EDGE ON <edge_type>
  2. <src_vid> -> <dst_vid> [@rank]
  3. SET <update_prop>
  4. [WHEN <condition>]
  5. [YIELD <properties>]
参数是否必须说明示例
ON <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子句。

  • 属性是否有默认值。

例如:

  • 要插入的边包含基于边类型serve的属性start_yearend_year

  • SET子句指定end_year = 2021

不同情况下的属性值如下表。

是否满足WHEN子句条件属性是否有默认值start_year属性值end_year属性值
默认值2021
NULL2021
默认值2021
NULL2021

示例如下:

  1. // 查看如下三个点是否有serve类型的出边,结果“Empty set”表示没有serve类型的出边。
  2. nebula> GO FROM "player666", "player667", "player668" \
  3. OVER serve \
  4. YIELD serve.start_year, serve.end_year;
  5. Empty set
  6. nebula> UPSERT EDGE on serve \
  7. "player666" -> "team200"@0 \
  8. SET end_year = 2021 \
  9. WHEN end_year == 2010 \
  10. YIELD start_year, end_year;
  11. +------------+----------+
  12. | start_year | end_year |
  13. +------------+----------+
  14. | __NULL__ | 2021 |
  15. +------------+----------+
  16. nebula> UPSERT EDGE on serve \
  17. "player666" -> "team200"@0 \
  18. SET end_year = 2022 \
  19. WHEN end_year == 2010 \
  20. YIELD start_year, end_year;
  21. +------------+----------+
  22. | start_year | end_year |
  23. +------------+----------+
  24. | __NULL__ | 2021 |
  25. +------------+----------+
  26. nebula> UPSERT EDGE on serve \
  27. "player667" -> "team200"@0 \
  28. SET end_year = 2022 \
  29. YIELD start_year, end_year;
  30. +------------+----------+
  31. | start_year | end_year |
  32. +------------+----------+
  33. | __NULL__ | 2022 |
  34. +------------+----------+
  35. nebula> UPSERT EDGE on serve \
  36. "player668" -> "team200"@0 \
  37. SET start_year = 2000, end_year = end_year + 1 \
  38. YIELD start_year, end_year;
  39. +------------+----------+
  40. | start_year | end_year |
  41. +------------+----------+
  42. | 2000 | __NULL__ |
  43. +------------+----------+

上面最后一个示例中,因为end_year没有默认值,插入边时,end_year默认值为NULL,执行end_year = end_year + 1后仍为NULL。如果end_year有默认值,则end_year = end_year + 1可以正常执行,例如:

  1. nebula> CREATE EDGE serve_with_default(start_year int, end_year DEFAULT 2010);
  2. Execution succeeded
  3. nebula> UPSERT EDGE on serve_with_default \
  4. "player668" -> "team200" \
  5. SET end_year = end_year + 1 \
  6. YIELD start_year, end_year;
  7. +------------+----------+
  8. | start_year | end_year |
  9. +------------+----------+
  10. | __NULL__ | 2011 |
  11. +------------+----------+

修改存在的边

如果边存在,且满足WHEN子句的条件,就会修改边的属性值。

  1. nebula> MATCH (v:player{name:"Ben Simmons"})-[e:serve]-(v2) \
  2. RETURN e;
  3. +-----------------------------------------------------------------------+
  4. | e |
  5. +-----------------------------------------------------------------------+
  6. | [:serve "player149"->"team219" @0 {end_year: 2019, start_year: 2016}] |
  7. +-----------------------------------------------------------------------+
  8. nebula> UPSERT EDGE on serve \
  9. "player149" -> "team219" \
  10. SET end_year = end_year + 1 \
  11. WHEN start_year == 2016 \
  12. YIELD start_year, end_year;
  13. +------------+----------+
  14. | start_year | end_year |
  15. +------------+----------+
  16. | 2016 | 2020 |
  17. +------------+----------+

如果边存在,但是不满足WHEN子句的条件,修改不会生效。

  1. nebula> MATCH (v:player{name:"Ben Simmons"})-[e:serve]-(v2) \
  2. RETURN e;
  3. +-----------------------------------------------------------------------+
  4. | e |
  5. +-----------------------------------------------------------------------+
  6. | [:serve "player149"->"team219" @0 {end_year: 2020, start_year: 2016}] |
  7. +-----------------------------------------------------------------------+
  8. nebula> UPSERT EDGE on serve \
  9. "player149" -> "team219" \
  10. SET end_year = end_year + 1 \
  11. WHEN start_year != 2016 \
  12. YIELD start_year, end_year;
  13. +------------+----------+
  14. | start_year | end_year |
  15. +------------+----------+
  16. | 2016 | 2020 |
  17. +------------+----------+