3.3.3 WHERE语句
WHERE在MATCH或者OPTINAL MATCH语句中添加约束,或者与WITH一起使用来过滤结果。
WHERE不能单独使用,它只能作为MATCH、OPTINAL MATCH、START和WITH的一部分。如果是用在WITH和START中,它用于过滤结果。对于MATCH和OPTINAL MATCH,WHERE为模式增加约束,它不能看作是匹配完成后的结果过滤。
WHERE图例如图3-7所示。
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P141_89012.jpg?sign=1739223730-jNm4nBfFQZwwQsgf2c5DV5ea7LFkIEoZ-0-a5cc7f4f11def268780ff9a57be1acf2)
图3-7 WHERE图例
3.3.3.1 基本使用
1.布尔运算
可以在WHERE中使用布尔运算符,如AND、OR,以及布尔函数NOT。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P141_102598.jpg?sign=1739223730-HGf626cvhAPkriVkUQaXDCRVsuq5Lu92-0-4a1c43aff6093e4677ab447316af703e)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P141_101583.jpg?sign=1739223730-8BoEIu7FfRezZQpo6k77BMOi6BRSy5rD-0-1fe1972fcbf7f50400a47996cfa64038)
2.节点标签的过滤
可以在WHERE中类似使用WHERE n:foo写入标签断言来过滤节点。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P141_102599.jpg?sign=1739223730-jAb1f5qYce220jlw6F0VRhW7rT0PGCrl-0-9588d7ba2ca06cfe133d7e5d1e0102a4)
将返回Andres节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P141_101586.jpg?sign=1739223730-gxIYuglCxSVyq9FsWNUCoPavWREbemh1-0-d988ee9d70a68a9d9595e04c1c091ae5)
提示:提示:如果要查询不包含某个标签的其他所有节点的反向查询,可在WHERE后加NOT。
3.节点属性的过滤
可以在WHERE语句中对节点的属性进行过滤。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_102600.jpg?sign=1739223730-4Q96SmLIrbhMgxnAjy1Gm7MAn4REqzmR-0-da45b1e4c153f03abc537a02dc4c9c7f)
返回了Tobias节点,因为其年龄小于30。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_101589.jpg?sign=1739223730-AOjSnwmBgAFKI1Uuw7Ru8Uhqnn50bUdE-0-67636d21d8594687d124cc4fc092b23e)
4.关系属性的过滤
要对关系的属性进行过滤,可在WHERE中添加如下关键词:
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_102601.jpg?sign=1739223730-edVno9HONbz71yDtYsLb3ByQNsVQZKt6-0-111b4be3a27d3193de2221b8fd2ee902)
返回了Peter,因为Andres自1999年就认识他了。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_101592.jpg?sign=1739223730-OLqV6z93pnLTty2CtbtuQEMnhhrMComT-0-6a46390a40713c50975331d6c0a58b68)
5.动态节点属性过滤
以方括号语法的形式使用动态计算的值来过滤属性。
参数:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_102602.jpg?sign=1739223730-MpGdeXjkHR5Bu6gtIi2TYThOW0c3chNq-0-61ec4ba1ca435f0d18da93f73764fcd3)
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_89134.jpg?sign=1739223730-kY1HFoM1rZBOd5WgRCWAQuGbBR2MdrmC-0-a2a7aadeca82aa92b5d31a978ce82d28)
返回了“Tobias”,因为他的年龄小于30。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_101595.jpg?sign=1739223730-xWTrQElPYvYcEpp7cWNVkOhyALdkhI0f-0-6204f796e791c7280cf691bf99fc69a5)
6.属性存在性检查
可以使用exists()检查节点或者关系的某个属性是否存在。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_102604.jpg?sign=1739223730-KYvf7Exf7fbi6LeNdfyNWLyVhGOleuif-0-fca38ea567c4f5c1e8fdcf1e744c371a)
返回了Andres,因为只有belt属性。
提示:提示:has()函数已被移除,并被exists()替代了。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_101597.jpg?sign=1739223730-8qbHC1gBPR0mBwzO381jJtCmLjHsmHoy-0-f807d2f92ba0db5a0164c4f99672ac2e)
3.3.3.2 字符串匹配
可以用START WITH和ENDS WITH来匹配字符串的开始和结尾。如果不关心所匹配字符串的位置,可以用CONTAINS,匹配是区分大小写的。
1.匹配字符串的开始
STARTS WITH用于以大小写敏感的方式匹配字符串的开始。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_102605.jpg?sign=1739223730-0dxiCFRFP1aMVjzToF5bDQyMbrrEKPW2-0-e43720a164c0c4171536afd403e88775)
返回了Peter,因为其名字以“Pet”开始。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_101600.jpg?sign=1739223730-BqRaK9oBDvET0RLHdpWDsvMSJxskzZbi-0-943c1716a442f9d77f59ffb04cbda69a)
2.匹配字符串的结尾
ENDS WITH用于以大小写敏感的方式匹配字符串的结尾。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_102606.jpg?sign=1739223730-ayTTikTfrRoa0gnhKG1WqCtsEh5bZBfY-0-70601bb63441b5a15416e47aa980edfb)
返回了Peter,因为其名字以“ter”结尾。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_101603.jpg?sign=1739223730-Njf3EZCQ3s2EN3F8D29Sp27jx3wtFE5d-0-5d9ccbfa0037c1254efe39f0366262df)
3.字符串包含
CONTAINS用于检查字符串中是否包含某个字符串,它是大小写敏感的,且不关心匹配部分在字符串中的位置。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_102607.jpg?sign=1739223730-seMj0xlyaNXPzpkIifQku1EKbJc4jB5n-0-5b33881f7b15dff6f1059c230c8fe720)
返回了Peter,因为其名字包含了“ete”字符串。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_101606.jpg?sign=1739223730-Dce7xBjQVQYjWemOH29bP6l7ccFJnDlb-0-4443d66faf24374ac8d328ef43aa264f)
4.字符串反向匹配
使用NOT关键词可以返回不满足给定字符串匹配要求的结果。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_102608.jpg?sign=1739223730-d3gcEg7UC18e1lHGffaWZtCcIMBJyOJi-0-d11fec1e5aabe9168e0334a04769b5ec)
返回了Peter,因为其名字不以“s”结尾。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P145_101609.jpg?sign=1739223730-d09Ryj4T4FM0kArCoyGQgcTNuQKKcPPK-0-7694984f7f69bcf109b1a5173a26c24b)
3.3.3.3 正则表达式
Cypher支持正则表达式过滤。正则表达式的语法继承来自Java正则表达式(5)。它支持字符串如何匹配标记,包括不区分大小写(?i)、多行(?m)和单行(?s)。标记放在正则表达式的开头,例如MATCH (n) WHERE n.name =~ '(?i)Lon.*' RETURN n将返回名字为London和LonDoN的节点。
1.正则表达式
可以使用=~ 'regexp'来进行正则表达式的匹配。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P145_102609.jpg?sign=1739223730-Oz1wqYdQaWmDJZpTFmjdsPhHMcfha8fV-0-ff5edd2376c2a9c9bb9e485a680b2376)
返回了Tobias,因为其名字以“Tob”开始。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P145_101612.jpg?sign=1739223730-9PDUiN7foK8RSNnPL4a4aQdaYz3IxGEL-0-5c0f92563d235c78ed9d1547296dbc95)
2.正则表达式中的转义字符
如果需要在正则表达式中插入斜杠,则需要使用转义字符。
注意:字符串中的反斜杠也需要转义。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P145_102610.jpg?sign=1739223730-LdLCdrSCJFWTCCfLXpgIlOZemNVuTX9Q-0-ab206df90304441ebb146f1694fdb971)
返回了Tobias,因为其地址在“Sweden/Malmo”。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_89320.jpg?sign=1739223730-xPCrzLr8xxQ8TH5M1Ejv5f5RqcHyv766-0-6134b9bae6e800dc2f21b1730fe5ffb6)
3.正则表达式的非大小写敏感
在正则表达式前面加入“(?i)”之后,整个正则表达式将变成非大小写敏感。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_102611.jpg?sign=1739223730-evoyPYK6XZ1N4B78uUGq9WeMgJImt8YS-0-174b5cc94fde270fe221e28814cd2279)
返回了Andres,因为其名字在不考虑大小写的情况下以“ANDR”开始。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_101616.jpg?sign=1739223730-bIMrPF2GnZnwnue3FUYVBvl6aFB2Er2K-0-8e14880bfa33c156c9d9bba7a685da30)
3.3.3.4 在WHERE中使用路径模式
1.模式过滤
模式是返回一个路径列表的表达式。列表表达式也是一种断言,空列表代表false,非空列表代表true。因此,模式不仅仅是一种表达式,同时也是一种断言。模式的局限性在于只能在单条路径中表达它,不能像在MATCH语句中那样使用逗号分隔多条路径,但可以通过AND组合多个模式。
提示:不能在WHERE中的模式引入新的变量。尽管它看起来与MATCH中的模式类似。但MATCH(a)-[]→(b)与WHERE (a)-[]→(b)有很大的不同,前者将产生一个它匹配到的a和b之间的路径子图,而后者是排除匹配到的a和b之间没有一个有向关系链的任何子图。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_102612.jpg?sign=1739223730-zGbrDvhUYet7tWkH3CtTBM6KUu7ZFBOP-0-c7a81e70a65194508190b8f5f874e19f)
结果将返回有外向关系指向Tobias的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_101618.jpg?sign=1739223730-8iMtNbUWhqOCR0WJX8Wv0EyDMaPIA9Ka-0-65b4414841889296cc7a05d05c570ab9)
2.模式中的NOT过滤
NOT可用于排除某个模式。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_102613.jpg?sign=1739223730-zE3M9ZbZI0z1dFEVd0u1LKkuvtUW5Xlo-0-712b24b6ac93818cc94538fd66b37cf1)
结果将返回没有外向关系指向Peter的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_101621.jpg?sign=1739223730-WLXsLtHi0fej4XxZO345hdg9TPKjhbSm-0-61e0af80bb2d6722793829f9f8749052)
3.模式中的属性过滤
可以在模式中添加属性来过滤结果。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_102614.jpg?sign=1739223730-VCJYQyWt50mhWU8p17pZfInCyhp7KapC-0-8f3484ddbc3c6bc9a4648a1696cc0328)
结果将返回与节点Tobias有KNOWS关系的所有节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_101624.jpg?sign=1739223730-NlVM1iGIrizzSnalNaoBZ6NlwZxmO35k-0-b9cb30bb668cfb2f4128f58b2fd0b30a)
4.关系类型过滤
可以在MATCH模式中添加关系类型,但有时候希望在类型过滤上具有丰富的功能。这时,可以将类型与其他进行比较。例如,下面是一个对关系类型与一个正则表达式进行比较的例子。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_102615.jpg?sign=1739223730-4T7uGjavgslzAlbmp43Cop3ppQNFCyC5-0-b63c80a4582da08df7487893d9455c97)
该查询将返回与Andres节点以“K”开始的所有关系。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_101627.jpg?sign=1739223730-gWzWcMY0SyM3IFDGynMtlVGgue80X7Ml-0-ac648327eef3a8109fb7de4451cc507e)
5.在WHERE中使用简单存在子查询
可以在内部MATCH子句中使用从外部引入的变量,如以下示例所示:
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_102616.jpg?sign=1739223730-IDUwd8MH3beKOCyfXfiqo6clhnUecznM-0-69a8cdba4d98192b6435394f11518fa5)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_101630.jpg?sign=1739223730-PVJxuSAnzbOJN5vh5preJojedafmOkCL-0-11c34f99f5640e7432965557623febad)
6.嵌套存在子查询
存在子查询可以嵌套,如下例所示。嵌套也会影响范围。这意味着可以从子查询内部访问所有变量,这些变量要么在外部范围内,要么在同一个子查询中定义。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_102617.jpg?sign=1739223730-M9Xe61JAe7H5zcIVpUJDUPFXE7o7Po6H-0-10b2dfdb28627b32c826a701c6d88fb9)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_101633.jpg?sign=1739223730-bbOg4QgKL7Qc9CKvvJ0svi3Giaimukka-0-a823f9a55b0012a7e3821a2bbd1defdb)
3.3.3.5 列表
IN运算符:可以使用IN运算符检查列表中是否存在某个元素。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_102618.jpg?sign=1739223730-vWD1b6mhUhEoUnGqXH899Iu5Ap4Cla4C-0-5f253f435271446caa5f114cdb66eb6e)
以上查询将检查字符串列表中是否存在某个属性。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_101636.jpg?sign=1739223730-DeQRGvxD7TbThk6as2VvwlHdyZjzChJm-0-cba12df917a30c921b74e38445cd8bd8)
3.3.3.6 不存在的属性和值
如果属性不存在,对它的判断默认返回false。对于不存在的属性值则当作null,在下面例子中,对于没有belt属性的节点的比较将返回false。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_102619.jpg?sign=1739223730-2pUg2yiYDf3l1liJRI9L9UBIS6k3GryT-0-6bf0224fd493a3c849b8b56368093db9)
结果将仅返回belt为white的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_101639.jpg?sign=1739223730-tcQaGH9dwJiRxVkAWW0lkSck5BdbpDng-0-89e646d9df7db2f008f7dc1c84afb0db)
1.属性不存在默认为true的情况
通过如下查询语句可以实现:如果要比较的属性存在,则可以与期望的值进行比较;如果不存在(IS NULL),则默认值为true。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_102620.jpg?sign=1739223730-UIGS0ZnPDLTv541ihZnfvPKqkgmRVQrD-0-0e05e9966f212e1a284ec9f8a4532b2b)
结果将返回满足belt属性值为white和不存在belt属性的所有节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_101642.jpg?sign=1739223730-po6yPTjq1cB18zXNo5iRv7Em2UDsXnzJ-0-bb44653cdbf540962cdd3cf06d93a3f3)
2.空值过滤
有时候需要测试某个值或变量是否为null。在Cypher中与SQL类似,可以使用IS NULL,相反,“不为空”则使用IS NOT NULL,尽管也可以使用NOT (IS NULL x)。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_102621.jpg?sign=1739223730-fAPoSR8YSzslKwgR2Ms5A6pzZ2DQC6Vn-0-eec42fa4a6ce3b28db49c71567f603b1)
结果将返回name属性值为Peter的且不存在belt属性的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_101645.jpg?sign=1739223730-N6bXtd2YA3P0JA44drjW5VDW1ry0hNj7-0-5b7d87ef3912edf4a010d4971dbe9ee9)
3.3.3.7 使用范围
1.简单范围
可以使用不等运算符<、>=和>检查某个元素是否在指定的范围。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_102622.jpg?sign=1739223730-l93jhzzMoIxQfrvZkIjPNDnaBn7UIgLb-0-a262dd189deefa16fa9f5658d0bfc096)
结果将返回节点的name属性值大于或等于Peter的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_101648.jpg?sign=1739223730-3dpOUx5njzWbsXhxHW6SW9QW3YzCju9D-0-cd4f7523eda4a289c0469fb456f0ea36)
2.范围的组合
可以将多个不等式组合成一个范围。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_102623.jpg?sign=1739223730-NSrIXxhgDvFmx0ODDkXmXnpHp9PHbkk8-0-10e50c170dc2d7364155d064a8bc458c)
结果将返回name属性值介于Andres和Tobias之间的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P151_101650.jpg?sign=1739223730-4jbrgukR4UZ8FuzbhQ7FgneQAqDTq7li-0-fc8e5785ea45d9bebecb97840cb25161)