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之间的节点。
结果: