3.3.3 WHERE语句

WHERE在MATCH或者OPTINAL MATCH语句中添加约束,或者与WITH一起使用来过滤结果。

WHERE不能单独使用,它只能作为MATCH、OPTINAL MATCH、START和WITH的一部分。如果是用在WITH和START中,它用于过滤结果。对于MATCH和OPTINAL MATCH,WHERE为模式增加约束,它不能看作是匹配完成后的结果过滤。

WHERE图例如图3-7所示。

图3-7 WHERE图例

3.3.3.1 基本使用

1.布尔运算

可以在WHERE中使用布尔运算符,如AND、OR,以及布尔函数NOT。

查询:

结果:

2.节点标签的过滤

可以在WHERE中类似使用WHERE n:foo写入标签断言来过滤节点。

查询:

将返回Andres节点。

结果:

提示:提示:如果要查询不包含某个标签的其他所有节点的反向查询,可在WHERE后加NOT。

3.节点属性的过滤

可以在WHERE语句中对节点的属性进行过滤。

查询:

返回了Tobias节点,因为其年龄小于30。

结果:

4.关系属性的过滤

要对关系的属性进行过滤,可在WHERE中添加如下关键词:

查询:

返回了Peter,因为Andres自1999年就认识他了。

结果:

5.动态节点属性过滤

以方括号语法的形式使用动态计算的值来过滤属性。

参数:

查询:

返回了“Tobias”,因为他的年龄小于30。

结果:

6.属性存在性检查

可以使用exists()检查节点或者关系的某个属性是否存在。

查询:

返回了Andres,因为只有belt属性。

提示:提示:has()函数已被移除,并被exists()替代了。

结果:

3.3.3.2 字符串匹配

可以用START WITH和ENDS WITH来匹配字符串的开始和结尾。如果不关心所匹配字符串的位置,可以用CONTAINS,匹配是区分大小写的。

1.匹配字符串的开始

STARTS WITH用于以大小写敏感的方式匹配字符串的开始。

查询:

返回了Peter,因为其名字以“Pet”开始。

结果:

2.匹配字符串的结尾

ENDS WITH用于以大小写敏感的方式匹配字符串的结尾。

查询:

返回了Peter,因为其名字以“ter”结尾。

结果:

3.字符串包含

CONTAINS用于检查字符串中是否包含某个字符串,它是大小写敏感的,且不关心匹配部分在字符串中的位置。

查询:

返回了Peter,因为其名字包含了“ete”字符串。

结果:

4.字符串反向匹配

使用NOT关键词可以返回不满足给定字符串匹配要求的结果。

查询:

返回了Peter,因为其名字不以“s”结尾。

结果:

3.3.3.3 正则表达式

Cypher支持正则表达式过滤。正则表达式的语法继承来自Java正则表达式(5)。它支持字符串如何匹配标记,包括不区分大小写(?i)、多行(?m)和单行(?s)。标记放在正则表达式的开头,例如MATCH (n) WHERE n.name =~ '(?i)Lon.*' RETURN n将返回名字为London和LonDoN的节点。

1.正则表达式

可以使用=~ 'regexp'来进行正则表达式的匹配。

查询:

返回了Tobias,因为其名字以“Tob”开始。

结果:

2.正则表达式中的转义字符

如果需要在正则表达式中插入斜杠,则需要使用转义字符。

注意:字符串中的反斜杠也需要转义。

查询:

返回了Tobias,因为其地址在“Sweden/Malmo”。

结果:

3.正则表达式的非大小写敏感

在正则表达式前面加入“(?i)”之后,整个正则表达式将变成非大小写敏感。

查询:

返回了Andres,因为其名字在不考虑大小写的情况下以“ANDR”开始。

结果:

3.3.3.4 在WHERE中使用路径模式

1.模式过滤

模式是返回一个路径列表的表达式。列表表达式也是一种断言,空列表代表false,非空列表代表true。因此,模式不仅仅是一种表达式,同时也是一种断言。模式的局限性在于只能在单条路径中表达它,不能像在MATCH语句中那样使用逗号分隔多条路径,但可以通过AND组合多个模式。

提示:不能在WHERE中的模式引入新的变量。尽管它看起来与MATCH中的模式类似。但MATCH(a)-[]→(b)与WHERE (a)-[]→(b)有很大的不同,前者将产生一个它匹配到的a和b之间的路径子图,而后者是排除匹配到的a和b之间没有一个有向关系链的任何子图。

查询:

结果将返回有外向关系指向Tobias的节点。

结果:

2.模式中的NOT过滤

NOT可用于排除某个模式。

查询:

结果将返回没有外向关系指向Peter的节点。

结果:

3.模式中的属性过滤

可以在模式中添加属性来过滤结果。

查询:

结果将返回与节点Tobias有KNOWS关系的所有节点。

结果:

4.关系类型过滤

可以在MATCH模式中添加关系类型,但有时候希望在类型过滤上具有丰富的功能。这时,可以将类型与其他进行比较。例如,下面是一个对关系类型与一个正则表达式进行比较的例子。

查询:

该查询将返回与Andres节点以“K”开始的所有关系。

结果:

5.在WHERE中使用简单存在子查询

可以在内部MATCH子句中使用从外部引入的变量,如以下示例所示:

查询:

结果:

6.嵌套存在子查询

存在子查询可以嵌套,如下例所示。嵌套也会影响范围。这意味着可以从子查询内部访问所有变量,这些变量要么在外部范围内,要么在同一个子查询中定义。

查询:

结果:

3.3.3.5 列表

IN运算符:可以使用IN运算符检查列表中是否存在某个元素。

查询:

以上查询将检查字符串列表中是否存在某个属性。

结果:

3.3.3.6 不存在的属性和值

如果属性不存在,对它的判断默认返回false。对于不存在的属性值则当作null,在下面例子中,对于没有belt属性的节点的比较将返回false。

查询:

结果将仅返回belt为white的节点。

结果:

1.属性不存在默认为true的情况

通过如下查询语句可以实现:如果要比较的属性存在,则可以与期望的值进行比较;如果不存在(IS NULL),则默认值为true。

查询:

结果将返回满足belt属性值为white和不存在belt属性的所有节点。

结果:

2.空值过滤

有时候需要测试某个值或变量是否为null。在Cypher中与SQL类似,可以使用IS NULL,相反,“不为空”则使用IS NOT NULL,尽管也可以使用NOT (IS NULL x)。

查询:

结果将返回name属性值为Peter的且不存在belt属性的节点。

结果:

3.3.3.7 使用范围

1.简单范围

可以使用不等运算符<、>=和>检查某个元素是否在指定的范围。

查询:

结果将返回节点的name属性值大于或等于Peter的节点。

结果:

2.范围的组合

可以将多个不等式组合成一个范围。

查询:

结果将返回name属性值介于Andres和Tobias之间的节点。

结果: