语法-表达式

Neo
Neo
2022-03-12 / 0 评论 / 54 阅读

本节内容源自Cypher官方手册V4.4版,笔者对其进行学习、翻译、记录。

通用表达式

在 Cypher 中,如果其内部表达式有null,则其计算结果大多都为null。值得注意的例外是运算符 IS NULL和IS NOT NULL.

Cypher 中的表达式可以是:

  • 十进制(整数或浮点数)文字:13, -40000, 3.14

  • 科学记数法的十进制(整数或浮点数)文字:6.022E23.

  • 十六进制整数文字(以0x开头):0x13af, 0xFC3A9, -0x66eff.

  • 八进制整数文字(以0o开头):0o1372, 02127, -0o5671.

  • 字符串文字:'Hello', "World".

  • 布尔文字:true, false.

  • 变量:n, x, rel, myFancyVariable, A name with weird stuff in it[]!.

  • 属性:n.prop, x.prop, rel.thisProperty, myFancyVariable.(weird property name).

  • 动态属性:n["prop"], rel[n.city + n.zip], map[coll[0]].

  • 参数:$param, $0.

  • 表达式列表:['a', 'b'], [1, 2, 3], ['a', 2, n.property, $param], [].

  • 函数调用:length(p), nodes(p).

  • 聚合函数:avg(x.prop), count(*).

  • 路径模式:(a)-[r]->(b), (a)-[r]-(b), (a)--(b), (a)-->()<--(b).

  • 运算符应用程序:1 + 2, 3 < 4.

  • 判断表达式:a.prop = 'Hello', length(p) > 10, a.name IS NOT NULL.

  • 存在子查询是返回 true 或 false的表达式 EXISTS { MATCH (n)-[r]→(p) WHERE p.name = 'Sven' }。

  • 正则表达式:a.name =~ 'Tim.*'.

  • 区分大小写的字符串匹配表达式:a.surname STARTS WITH 'Sven',a.surname ENDS WITH 'son'或a.surname CONTAINS 'son'.

  • CASE表达。

关于字符串的注意事项

字符串文字可以包含以下转义序列:
|转义序列|字符|
|-------|-------|
|\t|Tab|
|\b|空格|
|\n|新行|
|\r|回车|
|\f|换页|
|'|单引号|
|"|双引号|
|\|反斜杠|
|\uxxxx|Unicode UTF-16 代码点(必须跟随 4 个十六进制数字\u)|
|\Uxxxxxxxx|Unicode UTF-32 代码点(必须跟随 8 个十六进制数字\U)|

CASE表达式

通用条件表达式可以使用CASE构造来表达。Cypher中存在两种变体CASE:简单形式,允许将表达式与多个值进行比较,以及通用形式,允许表达多个条件语句。

如果您想在后续子句或语句中使用结果,则 CASE 只能用作 RETURN 或 WITH 的一部分。

下图用于以下示例:
image.png

简单CASE形式:将表达式与多个值进行比较

计算表达式,并按顺序与WHEN子句进行比较,直到找到匹配项。如果未找到匹配项,ELSE则返回子句中的表达式。但是,如果没有 ELSE case 并且没有找到匹配项,则会返回null。

CASE test
  WHEN value THEN result
  [WHEN ...]
  [ELSE default]
END

参数

  • test:一个有效的表达式。
  • value:一个表达式,其结果将与 test 进行比较。
  • result:如果value匹配,这是作为输出返回的表达式test。
  • default:如果未找到匹配项,default则返回。

示例

MATCH (n)
RETURN
CASE n.eyes
  WHEN 'blue'  THEN 1
  WHEN 'brown' THEN 2
  ELSE 3
END AS result
2
1
3
2
1
Rows: 5

通用CASE形式:允许表达多个条件

按顺序判断,直到true找到一个值,并使用结果值。如果未找到匹配项,ELSE 则返回子句中的表达式。但是,如果没有ELSE case 并且没有找到匹配项,null则会返回。

示例

MATCH (n)
RETURN
CASE
  WHEN n.eyes = 'blue' THEN 1
  WHEN n.age < 40      THEN 2
  ELSE 3
END AS result
2
1
3
3
1
Rows: 5

区分何时使用简单形式和通用CASE形式

由于两种形式的语法非常相似,有时可能一开始就不清楚使用哪种形式。我们通过以下查询来说明这种情况,其中有一个预期age_10_years_ago是-1 如果 n.ageis null:

MATCH (n)
RETURN n.name,
CASE n.age
  WHEN n.age IS NULL THEN -1
  ELSE n.age - 10
END AS age_10_years_ago

但是,由于此查询是使用简单CASE形式编写的,而不是age_10_years_ago针对-1名为 Daniel 的节点,它是null. n.age这是因为在和之间进行了比较n.age IS NULL。由于n.age IS NULL是布尔值,并且n.age是整数值,因此WHEN n.age IS NULL THEN -1永远不会采用分支。这导致ELSE n.age - 10分支被取而代之,返回null.

n.name	age_10_years_ago
"Alice" 28
"Bob" 15
"Charlie" 43
"Daniel" <null>
"Eskil" 31
Rows: 5

更正后的查询,如预期的那样,由以下通用CASE形式给出:

MATCH (n)
RETURN n.name,
CASE
  WHEN n.age IS NULL THEN -1
  ELSE n.age - 10
END AS age_10_years_ago
n.name	age_10_years_ago
"Alice" 28
"Bob" 15
"Charlie" 43
"Daniel" -1
"Eskil" 31

CASE在随后的子句或语句中使用结果

您可以使用 CASE 的结果来设置节点或关系的属性。例如,您可以为表达式选择的节点设置属性,而不是直接指定节点:

MATCH (n)
WITH n,
CASE n.eyes
  WHEN 'blue'  THEN 1
  WHEN 'brown' THEN 2
  ELSE 3
END AS colourCode
SET n.colourCode = colourCode
(empty result)
Rows: 0
Properties set: 5

有关使用该SET子句的更多信息,请参阅SET。