![精通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=1738814471-u2Lo00JJuCwai9pyY92iS01Fa6KW4SxR-0-25f2d5983e18fb3aae3cecaa169d7630)
图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=1738814471-aXRJISHKFYS9t4LMiyq8BNhBEYI1Veue-0-3872f3af18afa42a4952b826e0f820fb)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P141_101583.jpg?sign=1738814471-NL5QiSm7kJGc5pLE1PamkhnxPd58icx6-0-77727b5c2fdd823a9f70838ee90f3b09)
2.节点标签的过滤
可以在WHERE中类似使用WHERE n:foo写入标签断言来过滤节点。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P141_102599.jpg?sign=1738814471-cHjlCgOKMnwD8bLzlsaYn5AM3ArZOaYt-0-19ca5c61ef6d65c4f152c0676a9b694e)
将返回Andres节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P141_101586.jpg?sign=1738814471-fPuVEnnSmPUY1PBcYS7jHUc6dB0ytiIs-0-9c59f2eeb77d0556ddb70e0c21b78628)
提示:提示:如果要查询不包含某个标签的其他所有节点的反向查询,可在WHERE后加NOT。
3.节点属性的过滤
可以在WHERE语句中对节点的属性进行过滤。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_102600.jpg?sign=1738814471-cVHjAVQbs9h8c0dVqs4fkHpwu4evTOo5-0-b2a7e0930bd4ad6952b114267497f613)
返回了Tobias节点,因为其年龄小于30。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_101589.jpg?sign=1738814471-TPqmsVUe58Q5i8MH8RkOOXBqhX7fsdIq-0-e473c2b992de2da688cb9adb9a4c3ddf)
4.关系属性的过滤
要对关系的属性进行过滤,可在WHERE中添加如下关键词:
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_102601.jpg?sign=1738814471-QjPPfWvzWLTOmAIKmvjfhAMNqxD5Vygo-0-6fc7a6db69b50d12867f136735c2282b)
返回了Peter,因为Andres自1999年就认识他了。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_101592.jpg?sign=1738814471-HCPtFCx1wxenZ9qfZtIf4DTyPfi5CSvS-0-8b7446731a3df0b636e3e93d28a9f135)
5.动态节点属性过滤
以方括号语法的形式使用动态计算的值来过滤属性。
参数:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_102602.jpg?sign=1738814471-9BeeS6by7Dask5lON8AH29oxzhs7fBMc-0-8fb0ae18f7155a04228e3301363f2d1b)
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_89134.jpg?sign=1738814471-vYvkQcpVQfXyPo3xE9yYcpaL7czJbNfY-0-defb870902306aafc5a9a4678d211e43)
返回了“Tobias”,因为他的年龄小于30。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_101595.jpg?sign=1738814471-YV1E7SciN4B4c2G7UaQPJbU2UBRrPgzj-0-5b646a95ba332e3703e0c57c2ec9c744)
6.属性存在性检查
可以使用exists()检查节点或者关系的某个属性是否存在。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_102604.jpg?sign=1738814471-sVqRXETKPFSx7xUTeze0Udn5EJOMlneP-0-491d1018d103916356f3477a79e3cd81)
返回了Andres,因为只有belt属性。
提示:提示:has()函数已被移除,并被exists()替代了。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_101597.jpg?sign=1738814471-C7AzmNyxzaO8YkMYLdI1623ddjTNnA3B-0-5ca9467a5d68bc6dc0ab4632b4e350c8)
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=1738814471-ctoLIGLWLBT4KuffhxjiE3gkYZJdVaaq-0-e9c94b2c62393994e0d6d91afefa8af7)
返回了Peter,因为其名字以“Pet”开始。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_101600.jpg?sign=1738814471-FNgR7gp6cRohCLuWJ2E7VTXEQgovOVVu-0-d760fc00ef08d6d96cd046a9bf664ab2)
2.匹配字符串的结尾
ENDS WITH用于以大小写敏感的方式匹配字符串的结尾。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_102606.jpg?sign=1738814471-5SYhGJ7inv47dfV8wZ38ZdJO0i2vjq58-0-d90accdbaaf060b4a4e587e4aa2adc5f)
返回了Peter,因为其名字以“ter”结尾。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_101603.jpg?sign=1738814471-35niLBXtiU0EDhh2sqqZmQZe2s4oSvbr-0-d334d2faee876a5747e729a272be63b7)
3.字符串包含
CONTAINS用于检查字符串中是否包含某个字符串,它是大小写敏感的,且不关心匹配部分在字符串中的位置。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_102607.jpg?sign=1738814471-D6RwYIztabS1T0cD3lJOm6ZcV9j0u9ME-0-2eefae61731376cbc1d3b4277e39f708)
返回了Peter,因为其名字包含了“ete”字符串。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_101606.jpg?sign=1738814471-TruBCCyrhZ8mtVcjIUPflLTrpiw20kj1-0-246e2888ea97a71cebbdca1651bd69ac)
4.字符串反向匹配
使用NOT关键词可以返回不满足给定字符串匹配要求的结果。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_102608.jpg?sign=1738814471-ieJZLeadYSKK7u09S7ZhpEjOROm7LedR-0-7ddbbc01b0a8fd094b6c5e4cd5a48249)
返回了Peter,因为其名字不以“s”结尾。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P145_101609.jpg?sign=1738814471-3S4AVVuMuk3dcy9vG8DOGmy0sLTE29NK-0-bfb14ad3643ba5efce00df941544dd79)
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=1738814471-DhbJZCwMruz0gcCQiCW7WBt2RtSqBhSH-0-d8081927230326c30b85c32253fcc641)
返回了Tobias,因为其名字以“Tob”开始。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P145_101612.jpg?sign=1738814471-drnUPBlhQq5yysZr0tlvLNcWANAFCorS-0-c927a824c06c6a9929ea711fa6810a28)
2.正则表达式中的转义字符
如果需要在正则表达式中插入斜杠,则需要使用转义字符。
注意:字符串中的反斜杠也需要转义。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P145_102610.jpg?sign=1738814471-qBE9NL4yFGuOxMFs4SLqHLbI0dtBgJeu-0-4817ce2ed914d6a6dec314ec6edb128f)
返回了Tobias,因为其地址在“Sweden/Malmo”。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_89320.jpg?sign=1738814471-Ai5o5XirixNHFs4XD7sBovJC2ElbVN1O-0-70da654bd9a3e4c62dcb241c86b41a72)
3.正则表达式的非大小写敏感
在正则表达式前面加入“(?i)”之后,整个正则表达式将变成非大小写敏感。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_102611.jpg?sign=1738814471-09tjrfyzRs4rjrDaWzI7nBiQS1XTcfh2-0-0f5d7b000c1d2da9c4d0a242f54adb67)
返回了Andres,因为其名字在不考虑大小写的情况下以“ANDR”开始。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_101616.jpg?sign=1738814471-mhEexHE3iTRB7iwOnEroCyQyJX6hsmbR-0-919ceb9dff016a2a43595566631b2b49)
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=1738814471-83AtcWkkqgxdheyWSUOTFHf31bNJ5wdB-0-e22bbde04848ce739458da72004a5c94)
结果将返回有外向关系指向Tobias的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_101618.jpg?sign=1738814471-d7taqPy9iPrbRpLcTutoBYOsRWD2FTG6-0-236f07bf3c0c1c4e68656b6e710595c1)
2.模式中的NOT过滤
NOT可用于排除某个模式。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_102613.jpg?sign=1738814471-kyLPL21kyTt0QKRvxfE1zN7CXHQZLeRZ-0-29cb9c41a1d4431d3d2941ebc25cf361)
结果将返回没有外向关系指向Peter的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_101621.jpg?sign=1738814471-aIPDeS6LYY0hBJ0SSnoWnuJjzxV5ItMl-0-8fe52f1a793fc78499b5da96ca866e58)
3.模式中的属性过滤
可以在模式中添加属性来过滤结果。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_102614.jpg?sign=1738814471-kvJgugStm1Br965Yx3tfO12s1OgvZPGR-0-27a24def2cfe1af08b1c6da73e89dee1)
结果将返回与节点Tobias有KNOWS关系的所有节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_101624.jpg?sign=1738814471-SLeRFTDD6WOAKrURm4SQgLitimn0qbUd-0-2d97ec5f45a63b1bb9dedb5eede031b7)
4.关系类型过滤
可以在MATCH模式中添加关系类型,但有时候希望在类型过滤上具有丰富的功能。这时,可以将类型与其他进行比较。例如,下面是一个对关系类型与一个正则表达式进行比较的例子。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_102615.jpg?sign=1738814471-y6Be6GfOwd0VWAbrkedcIC9HLeImaXwb-0-8272d82d6ffb5ab533b565304df2e01c)
该查询将返回与Andres节点以“K”开始的所有关系。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_101627.jpg?sign=1738814471-LdnMhvHfqu24exj4hVpNx1ofMjbXoISk-0-fbb03501c65dc6f5fc73efeeab2a082c)
5.在WHERE中使用简单存在子查询
可以在内部MATCH子句中使用从外部引入的变量,如以下示例所示:
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_102616.jpg?sign=1738814471-d44T3bbCn0KveILfTENPJYLee19euryO-0-570c346efac3f7611f75f8adbc4c8227)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_101630.jpg?sign=1738814471-vyfbuO8Wj7ObTfAJzTVyLZdOPILlVIOn-0-e535f5a9f2508bc62ad2528b19b097f2)
6.嵌套存在子查询
存在子查询可以嵌套,如下例所示。嵌套也会影响范围。这意味着可以从子查询内部访问所有变量,这些变量要么在外部范围内,要么在同一个子查询中定义。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_102617.jpg?sign=1738814471-Xag9i3WLGSAMOXx3DjO6chMqJ0W5Azt8-0-54cb21ad04f2722748d27ec9a9f99c81)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_101633.jpg?sign=1738814471-RJHJt6Kyoa9l9xsvkzxBvspEEgpdrTsb-0-6d99b59ff0ff138fb1ffe29e6fec82ae)
3.3.3.5 列表
IN运算符:可以使用IN运算符检查列表中是否存在某个元素。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_102618.jpg?sign=1738814471-a9dBdRfnPJHT71l4efLHbqIIRIY5Uhjx-0-02f40ec42889af06edf2791f7411ca2b)
以上查询将检查字符串列表中是否存在某个属性。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_101636.jpg?sign=1738814471-y76tnR6K2bbFA2Pm1fEiZjPI6kYVsT68-0-23a220edbf8782c08630c54ee6868e41)
3.3.3.6 不存在的属性和值
如果属性不存在,对它的判断默认返回false。对于不存在的属性值则当作null,在下面例子中,对于没有belt属性的节点的比较将返回false。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_102619.jpg?sign=1738814471-hSDIm4caxFimhZ6dKHPNmmORYS6zMsTX-0-5ffdd10715aa4d728ffb44f05cb60f44)
结果将仅返回belt为white的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_101639.jpg?sign=1738814471-chBIftLNbbbUsohLYbHMzFQX5Teaumnp-0-8d5291dc3a6f19e317f65c90f7459a58)
1.属性不存在默认为true的情况
通过如下查询语句可以实现:如果要比较的属性存在,则可以与期望的值进行比较;如果不存在(IS NULL),则默认值为true。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_102620.jpg?sign=1738814471-bxLPjV6yaAVxOpY9JhzLv7VBqQchvzli-0-a5eb1448c5af2de03e44e779ee61c8b8)
结果将返回满足belt属性值为white和不存在belt属性的所有节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_101642.jpg?sign=1738814471-nO1MkFkz12CJQGMZ28RtTYYnvvIbxLAt-0-90986de25aae55616551b9012f41eac7)
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=1738814471-fUPuBi2jEZdqGrhI31t14PsWwlaQhRZO-0-37a81e00301d4f1cd6e7abb3d8689ce5)
结果将返回name属性值为Peter的且不存在belt属性的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_101645.jpg?sign=1738814471-4ZPrK4NKpxJgXdyAtWI0AxPM55YeZPeD-0-5c4544904332c322674a4ca69c9d0f3a)
3.3.3.7 使用范围
1.简单范围
可以使用不等运算符<、>=和>检查某个元素是否在指定的范围。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_102622.jpg?sign=1738814471-VAjPb6ErvNnObe7BZ2hv6qG78deUKNUE-0-cd707d5db77c18f1a5b67d02ade7fffc)
结果将返回节点的name属性值大于或等于Peter的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_101648.jpg?sign=1738814471-pa1RsZkM8nJTOgmlE507KhQwrOaLbOm7-0-b960d9eb31afe23f417e0948a1cd4619)
2.范围的组合
可以将多个不等式组合成一个范围。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_102623.jpg?sign=1738814471-3IPJnQ0ySpe7j5yJrCkhxufA3W8apGOa-0-5b144594a5d6cb797aa222b5401e9cb4)
结果将返回name属性值介于Andres和Tobias之间的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P151_101650.jpg?sign=1738814471-ZxW42rhb53DORcbFdJRuCNtqwIXc6meM-0-b50de98c55e5c647b4a50001a1adefb4)