![精通Neo4j](https://wfqqreader-1252317822.image.myqcloud.com/cover/113/47216113/b_47216113.jpg)
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=1739286976-TAjguLwAxyVDyubGE7vEGKZxxDO15wBo-0-d163421df1c2b02c1bae8d7702f886b0)
图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=1739286976-D7q8Ybo3ubkfZuEjEJxiBQQvquAIT2iO-0-c110ed4bf26888aee38153579ee4b497)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P141_101583.jpg?sign=1739286976-fSN7DnMwQ88ArHfPG0mYnUeAG1P7QLw6-0-6ada7f5835ccb217d7b02088530a546d)
2.节点标签的过滤
可以在WHERE中类似使用WHERE n:foo写入标签断言来过滤节点。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P141_102599.jpg?sign=1739286976-ccx6M3i2HF9vsjwe2jiCVlMyS4zlpqV9-0-190c88e45279225cc150bda3cc240c6e)
将返回Andres节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P141_101586.jpg?sign=1739286976-Ca7rYkymNh6ziHLPNN4nh9IlG7HDp73z-0-caf742e05b441d4b683bbca578de7aa1)
提示:提示:如果要查询不包含某个标签的其他所有节点的反向查询,可在WHERE后加NOT。
3.节点属性的过滤
可以在WHERE语句中对节点的属性进行过滤。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_102600.jpg?sign=1739286976-ekoRSFRT1VAR51F9hDbmeiCw1x8S7LiB-0-09e95243fbefc16402b2d062942526c0)
返回了Tobias节点,因为其年龄小于30。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_101589.jpg?sign=1739286976-wBF1UtghC7qbtukDe3rXzZpFuFrs5h9k-0-e467c6dd31d2a3a642b6f886ca17bee3)
4.关系属性的过滤
要对关系的属性进行过滤,可在WHERE中添加如下关键词:
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_102601.jpg?sign=1739286976-sdHPFb3NccaLTgeY3QgyU6e0srmSetfj-0-68d8bff294abc68eb73438416e69a886)
返回了Peter,因为Andres自1999年就认识他了。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_101592.jpg?sign=1739286976-Qf1SAUkyaWACMuZ3oypBxJJO3nPljBzh-0-07e9c454224f5765905210056db40920)
5.动态节点属性过滤
以方括号语法的形式使用动态计算的值来过滤属性。
参数:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_102602.jpg?sign=1739286976-SKmGP0aNsmsfVuIC9EreuPOLKP46JAMQ-0-cb2e1f21ac3bc742a87b9212855f1fc7)
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_89134.jpg?sign=1739286976-lbVnERXLmVIfgUxFrHr62p8smMPO7DrC-0-be9d2b4852c5e314142f40ed57f91581)
返回了“Tobias”,因为他的年龄小于30。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_101595.jpg?sign=1739286976-5PgrSRYTsDWYCPganTkGfkiwDQXpCbBH-0-e143714e7c9a2854566c76ef4819c0cb)
6.属性存在性检查
可以使用exists()检查节点或者关系的某个属性是否存在。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_102604.jpg?sign=1739286976-uLQBwxNDIayyZ9xqNClh41JRiMKoUxnS-0-fe6de976a1e24300ac056cad5b7d7a7b)
返回了Andres,因为只有belt属性。
提示:提示:has()函数已被移除,并被exists()替代了。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_101597.jpg?sign=1739286976-6NLdjBKLrBBzIGEWBGkixW0vje1L3m9X-0-191acba5e1406efd89a291917dddf0f5)
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=1739286976-7l3dM8ixybECxGEpYDXkvvesiSK8meNP-0-1dd9bab572bcd9f743de1695857d0f0c)
返回了Peter,因为其名字以“Pet”开始。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_101600.jpg?sign=1739286976-vpgp0qkmkcymwUx3mcVffSu4rlYYtSlL-0-0853d616c87ed8bf7ec53ebc6efe3091)
2.匹配字符串的结尾
ENDS WITH用于以大小写敏感的方式匹配字符串的结尾。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_102606.jpg?sign=1739286976-3JEJVME0uss8BTBro4lNsVVzv32Kjgz3-0-4e6be008ef93cda64aa74001c37bd060)
返回了Peter,因为其名字以“ter”结尾。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_101603.jpg?sign=1739286976-LCsrB6UWR3IXuiWL0Y0Fxo6Xod2Vj9Ql-0-9bf35fa9236b58811e9722b1e271b00c)
3.字符串包含
CONTAINS用于检查字符串中是否包含某个字符串,它是大小写敏感的,且不关心匹配部分在字符串中的位置。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_102607.jpg?sign=1739286976-OurgginEC1E7ZXK9Jrsj6eJGGp0Dwc8Z-0-2440210b7fb186ee07b9302c13df4e30)
返回了Peter,因为其名字包含了“ete”字符串。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_101606.jpg?sign=1739286976-UcsD68PR7QyytrQPanpEMAi4gwtQA5Ij-0-02e275ae9f6944d08b2d8713591ec8ba)
4.字符串反向匹配
使用NOT关键词可以返回不满足给定字符串匹配要求的结果。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_102608.jpg?sign=1739286976-SOucfftiJ8dR266rfWim6euM4TQuWQvC-0-b4d78fa1f39d193cdf9a107b79e63ade)
返回了Peter,因为其名字不以“s”结尾。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P145_101609.jpg?sign=1739286976-ddKfIW6kvLfqM92g76Uh2Kmp5HDlvEeb-0-425e5be58227d8db7dd3e81ddd22a085)
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=1739286976-94eBx7CQMlUCNsa0e9PhAkyXmHZJ1HfG-0-84d8c9b1c3e1cf7f95b694aa578a6332)
返回了Tobias,因为其名字以“Tob”开始。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P145_101612.jpg?sign=1739286976-ZCqMCp9Jpj6kDNxFhrmP96d9bkUbxKaL-0-d91b81fed792d9a4662bde537a317536)
2.正则表达式中的转义字符
如果需要在正则表达式中插入斜杠,则需要使用转义字符。
注意:字符串中的反斜杠也需要转义。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P145_102610.jpg?sign=1739286976-4Rsb1z3WjTkJIaEgbNCEVCSfiVVIAy2l-0-ae6c8b776a99da35780953efc7cbd99b)
返回了Tobias,因为其地址在“Sweden/Malmo”。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_89320.jpg?sign=1739286976-sBxLs28smvYMguoTNSOiMI2xEDJBgb9F-0-039dd4e4de71404096fcb020bf3488c7)
3.正则表达式的非大小写敏感
在正则表达式前面加入“(?i)”之后,整个正则表达式将变成非大小写敏感。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_102611.jpg?sign=1739286976-6itbu8iVB8dYdJqiPelri9sqrrww4FdW-0-45c6ce525693bed48a99a0601fa4a8a5)
返回了Andres,因为其名字在不考虑大小写的情况下以“ANDR”开始。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_101616.jpg?sign=1739286976-xX6h2bLkQwg4hvyKJ93BpbOFV6AHUPIP-0-c06157c9aaf2acd93886b0dc18466e8d)
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=1739286976-E9990VBiM6ouT6zEiAzU8QnpFPWJVVIC-0-3ede42ef889e2a14b070a1470bae50b4)
结果将返回有外向关系指向Tobias的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_101618.jpg?sign=1739286976-VYkjI5kYLQzWA6eZnBpaZbv8y2eArzll-0-e28e8a4c8b1ae9eaa7ce80407f2c9e67)
2.模式中的NOT过滤
NOT可用于排除某个模式。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_102613.jpg?sign=1739286976-iX30FH9ZdrvvupbnQUfC6nfX5nY9SHk6-0-c40aec5edf3adf3ebab7d9dfede028ae)
结果将返回没有外向关系指向Peter的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_101621.jpg?sign=1739286976-GMmMiVzntH60H0e3UGtqvOmM2GXQCR0d-0-7242388bbec0134f2016b0df9f66af35)
3.模式中的属性过滤
可以在模式中添加属性来过滤结果。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_102614.jpg?sign=1739286976-n5DzuSowcPhd7Zu5oLCgLxxvV75lepJE-0-ce5d7256b7d0eeca597fb1fdee77d7fa)
结果将返回与节点Tobias有KNOWS关系的所有节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_101624.jpg?sign=1739286976-JxkS4WXRXixYfICe9HTdBbJHNeSzG90I-0-8686609fc82fc65b3335da01137eda79)
4.关系类型过滤
可以在MATCH模式中添加关系类型,但有时候希望在类型过滤上具有丰富的功能。这时,可以将类型与其他进行比较。例如,下面是一个对关系类型与一个正则表达式进行比较的例子。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_102615.jpg?sign=1739286976-bocXEJYXVxI6HuMGSH4EpusGVWuGHvm8-0-5b03b3c9480032edbfd88183923cd00c)
该查询将返回与Andres节点以“K”开始的所有关系。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_101627.jpg?sign=1739286976-ChgctfW6yQffaB9YwtAMT5gg1qCMUqnV-0-a071126aa62e3c8fd1962fc3c9bfdae0)
5.在WHERE中使用简单存在子查询
可以在内部MATCH子句中使用从外部引入的变量,如以下示例所示:
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_102616.jpg?sign=1739286976-72xHK7uqUuTWnRgDdPSvmK9J6Bvu8OFR-0-e29ecfbda865db3f7f698595e2936289)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_101630.jpg?sign=1739286976-zuHsYVwEtvNHzSUlbhsHCUU6LtRvTt7i-0-a201626f6282eafdcf1f48ef17323597)
6.嵌套存在子查询
存在子查询可以嵌套,如下例所示。嵌套也会影响范围。这意味着可以从子查询内部访问所有变量,这些变量要么在外部范围内,要么在同一个子查询中定义。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_102617.jpg?sign=1739286976-PXMQuyTOABSu3MtFGMMBcc1oim4Yd2tt-0-a4799b88582fe751d26cbe0620b8b0c7)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_101633.jpg?sign=1739286976-J1bnS0i8YsXlGbAO0yVy1Yn9uBzwyajD-0-16d058a16d2acf885188afb893e955fd)
3.3.3.5 列表
IN运算符:可以使用IN运算符检查列表中是否存在某个元素。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_102618.jpg?sign=1739286976-RyJeOUA3uvNSIEO1A6aZfemjOU1FazMT-0-76d97d4d8d9f54ebd8f14f9b54e397c9)
以上查询将检查字符串列表中是否存在某个属性。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_101636.jpg?sign=1739286976-nTUIMA9vX7CeNeKBNVmlRx8dQ0x2Qosi-0-150a43c6f97d3d561b065ad7b640b986)
3.3.3.6 不存在的属性和值
如果属性不存在,对它的判断默认返回false。对于不存在的属性值则当作null,在下面例子中,对于没有belt属性的节点的比较将返回false。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_102619.jpg?sign=1739286976-7PoAKR5tDUNnUtomuVHcHVJrEUc9Cg7t-0-35184dbd8943d2809200b1018a1890e3)
结果将仅返回belt为white的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_101639.jpg?sign=1739286976-BCvA0OU5DEfrGMfJ0IdbdgPH2NBMewhA-0-f17f48e9b617a0eb2807e5bee911be2d)
1.属性不存在默认为true的情况
通过如下查询语句可以实现:如果要比较的属性存在,则可以与期望的值进行比较;如果不存在(IS NULL),则默认值为true。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_102620.jpg?sign=1739286976-VrvyccJ8H1GCgm1vAf0FygLuKJEXxILH-0-70bce7d95b0035d8cac7d0b6b175a486)
结果将返回满足belt属性值为white和不存在belt属性的所有节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_101642.jpg?sign=1739286976-QLJOA0SBFnszRWwdFMzOn6Eybob5PaS5-0-bfaf4a9df7762f10208ac2cc67320d05)
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=1739286976-Uge9pqixkl07JrMQEKExfD7znB3PHmZ6-0-2c1156935b91b163f69088e654f6f56a)
结果将返回name属性值为Peter的且不存在belt属性的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_101645.jpg?sign=1739286976-z95Pk4FoRsdgfHKTZqxby21VcxZexcSh-0-51e384ea3da19b06359fb7ba3e5fc032)
3.3.3.7 使用范围
1.简单范围
可以使用不等运算符<、>=和>检查某个元素是否在指定的范围。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_102622.jpg?sign=1739286976-49bRiWLyScVV8ni0UqVVOutfykEhP538-0-b814fbbefb2a4550478d9c80b7d0815e)
结果将返回节点的name属性值大于或等于Peter的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_101648.jpg?sign=1739286976-7d1lPwIxmN5LoFhAZJAyHYSlv8ZWnbis-0-f3790da2a710a3bd54e4d8ac6803e6ea)
2.范围的组合
可以将多个不等式组合成一个范围。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_102623.jpg?sign=1739286976-JDeyyBHAXUPJGvUXsc3bWWtckotaFgSy-0-aaeb738d510c99141dc3b53ce3dce0a4)
结果将返回name属性值介于Andres和Tobias之间的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P151_101650.jpg?sign=1739286976-1eJ6DVkHx83xiAaKxY0AgwowbWzAaYvG-0-51d178b8b43bd0679d5c411d6dca0c1a)