跳转至
开发版采用单机部署,无需产品 License 文件。需要多机部署或大规模性能测试? 了解企业版

子查询表达式

子查询表达式返回从某个查询中提取出的单个值或布尔值。

语法

subquery_value_expression
VALUE { procedure_body } EXISTS { procedure_body }

subquery_value_expression ::=
    'VALUE' '{' procedure_body '}'
  | 'EXISTS' '{' procedure_body '}'

参数

procedure_body

过程的处理逻辑,可以由原始值变量定义和以下类型的语句组成:

VALUE | EXISTS

子查询表达式的返回值类型。

  • VALUE:返回单个值。为此,procedure_body中的 RETURN 语句必须包含聚合返回项,或被LIMIT 1子句跟随。
    • 如果procedure_body的结果为空表,则子查询表达式的结果为NULL。
    • 如果procedure_body的结果是包含单个记录且单个字段的表,则子查询表达式的结果是该字段的值。
  • EXISTS:返回一个布尔值,表示某个模式是否在图中出现至少一次。
    • 如果procedure_body的执行结果是非空表,则子查询表达式的结果为true。
    • 如果procedure_body的结果为空表,则子查询表达式的结果为false。

工作图

子查询中可以使用USE声明工作图:

  • 如果子查询中没有USE,子查询继承外层查询的工作图。
  • 如果子查询中使用USE指定另一张图,子查询可以访问该图,并将返回的标量值或布尔值提供给外层查询。
  • 跨图关联数据时,建议为不同图中的图元素使用不同变量,并通过业务 ID 等属性值进行比较。

示例

以下示例基于示例数据集。

使用 LIMIT 1 返回单个值的子查询

RETURN VALUE {FOR i IN LIST [1,2,3,4] RETURN i ORDER BY i LIMIT 1} AS subquery_result

上述语句使用子查询VALUE {FOR i IN LIST [1,2,3,4] RETURN i ORDER BY i LIMIT 1}来查找列表[1,2,3,4]中的最小值,并返回该值。

返回:

+-----------------+
| subquery_result |
+-----------------+
| 1               |
+-----------------+

返回 NULL 的子查询

RETURN VALUE {FOR i IN LIST [] RETURN i ORDER BY i LIMIT 1} AS subquery_result

上述语句使用子查询VALUE {FOR i IN LIST [] RETURN i ORDER BY i LIMIT 1}来查找列表[]中的空值,并返回NULL值。

返回:

+-----------------+
| subquery_result |
+-----------------+
| null            |
+-----------------+

返回布尔值的子查询

'''
USE movie MATCH (a@Actor) 
WHERE EXISTS {USE movie MATCH (v@Actor) RETURN v} 
RETURN a.name 
Limit 5
'''

上述语句使用子查询EXISTS {}来查找图中是否存在任何演员。如果存在,则返回图中的五个演员的名称。

返回:

+------------------------+
| a.name                 |
+------------------------+
| Wilfried Hochholdinger |
| Martin LaSalle         |
| Lenny McLean           |
| Tadanobu Asano         |
| David Prowse           |
+------------------------+

在子查询中切换工作图

下面的查询在movie中匹配电影,并通过EXISTS {}子查询检查同一业务 ID 的电影是否存在于movie_2中:

'''
USE movie
MATCH (m:Movie)
WHERE EXISTS {
  USE movie_2
  MATCH (m2:Movie)
  WHERE m2.id = m.id
  RETURN m2
}
RETURN m.id, m.name
'''

外层查询和子查询分别使用变量m和m2表示两张图中的图元素,并通过业务属性id关联数据。

包含控制流语句的子查询

'''
USE movie MATCH (a@Actor)
LET v = VALUE {
    VALUE d = DATE "1950-01-01"
    IF a.birthDate > d THEN {
        RETURN "born_after_1950" AS result        
    } ELSE {
        RETURN "born_before_1950" AS result
    }
 }
RETURN a.name, v
LIMIT 5
'''

上述语句使用包含IF控制流语句的子查询VALUE {}来检查每个演员的出生日期是否在 1950 年 1 月 1 日之后。然后返回五个演员的姓名及检查结果。

返回:

+------------------+------------------+
| a.name           | v                |
+------------------+------------------+
| Jacques Weber    | born_before_1950 |
| Chia Hui Liu     | born_after_1950  |
| Ulrich Noethen   | born_after_1950  |
| Richard Pachorek | born_before_1950 |
| Christian Bale   | born_after_1950  |
+------------------+------------------+

包含变量操作语句的子查询

'''
USE movie MATCH (v@Actor) WHERE v.id IN [1,2,3,4,5]
LET d = VALUE {
  VALUE born_before_1950 = true
  IF v.birthDate < DATE "1950-01-01" THEN 
    {    
      SET born_before_1950 = true
      LOG_INFO(v.name, " was born before 1950.")
     } 
  ELSE 
    {  
      SET born_before_1950  = false     
      LOG_INFO(v.name, " was born in or after 1950.")
    }
  RETURN born_before_1950
  }
RETURN v.name, d AS born_before_1950  
'''

上述语句使用包含变量操作语句的子查询VALUE {}来检查 ID 在 1 到 5 之间的演员的出生日期是否在 1950 年 1 月 1 日之前。然后返回这些演员的姓名及检查结果。

返回:

+---------------+------------------+
| v.name        | born_before_1950 |
+---------------+------------------+
| Harrison Ford | true             |
| Mark Hamill   | false            |
| Peter Cushing | true             |
| Carrie Fisher | false            |
+---------------+------------------+
Log:
2026-01-20T10:07:47.149974 INFO  - Mark Hamill was born in or after 1950.
2026-01-20T10:07:47.149975 INFO  - Harrison Ford was born before 1950.
2026-01-20T10:07:47.150058 INFO  - Peter Cushing was born before 1950.
2026-01-20T10:07:47.150317 INFO  - Carrie Fisher was born in or after 1950.