![精通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=1739375505-eNSWJDycovltdVqxiLKGqM2hJvnn8t2M-0-a3a2952477c1f1d7595806dc87326416)
图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=1739375505-fgRA64q9nUV0ZNy944zXdciyNASpf0Z7-0-bb0388625e041805b170f5c34f9e38fd)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P141_101583.jpg?sign=1739375505-SsQMWKI7xBXxPxod6RtZ3ga4Fej6gFNk-0-cd5cf1a4df1e8a94f7c58a1cd0a652c6)
2.节点标签的过滤
可以在WHERE中类似使用WHERE n:foo写入标签断言来过滤节点。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P141_102599.jpg?sign=1739375505-dTZLrLvhNv8XTxVyaxNYwaqBbJVeUkpG-0-35c788f3f1891d3a4c42949657f44d4b)
将返回Andres节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P141_101586.jpg?sign=1739375505-f4PPzQWMJ8LIItNOu7nRL7vovKxtYgkD-0-0685c68d95f06da7016427cfb2ecbc6c)
提示:提示:如果要查询不包含某个标签的其他所有节点的反向查询,可在WHERE后加NOT。
3.节点属性的过滤
可以在WHERE语句中对节点的属性进行过滤。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_102600.jpg?sign=1739375505-xYrWd0vKvkDQazUNyVp2Kiiuvmp1GAqg-0-6c200b16738621cfc634948b99d1c5e6)
返回了Tobias节点,因为其年龄小于30。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_101589.jpg?sign=1739375505-sseFyGZs83I9FEVdxy15T0ErAhkxubg7-0-973d7b227478a8865e4497c891c7e42b)
4.关系属性的过滤
要对关系的属性进行过滤,可在WHERE中添加如下关键词:
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_102601.jpg?sign=1739375505-zdUr6CsOXd6Z6ELcP8PckW5j4AjdvoYC-0-cf290b5ef96276da380953564f07a299)
返回了Peter,因为Andres自1999年就认识他了。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_101592.jpg?sign=1739375505-118LiPfW6adCwLoJJasd8vUa96Kc3cTu-0-4c3b35f28e020b45205b4a628b1d92e2)
5.动态节点属性过滤
以方括号语法的形式使用动态计算的值来过滤属性。
参数:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_102602.jpg?sign=1739375505-UWb6oUOrwzmNuqf6vsZHZ4DMEhCaz8DM-0-2100a247ec5d33cc570882372b920d4d)
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_89134.jpg?sign=1739375505-kpcTSEg3xIj9ooG7cjJVSYLhktNpT3hD-0-7892f5f8d22f8911762bd4be84a298ac)
返回了“Tobias”,因为他的年龄小于30。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_101595.jpg?sign=1739375505-psMWticVy9xRpi8g4yqPLLc8gKB8vZ6a-0-9e53bf589b242b47e2449dde637b8e84)
6.属性存在性检查
可以使用exists()检查节点或者关系的某个属性是否存在。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_102604.jpg?sign=1739375505-rdK1kk8M8UMxCWu282vIZwtblMCi0B3X-0-503b6e8dc61d1309c039f2158efce18d)
返回了Andres,因为只有belt属性。
提示:提示:has()函数已被移除,并被exists()替代了。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_101597.jpg?sign=1739375505-15SAykcMaTDYCeelYMXfamU3h8kUHmMI-0-4e5042f0337d1aa2e37213c23bee1ab0)
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=1739375505-xAreWCMAV25YwhjpMWtYpwdTpEpNr6U8-0-8e2af299495c3a8b65126f4ce6a54dc4)
返回了Peter,因为其名字以“Pet”开始。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_101600.jpg?sign=1739375505-QtoBKkwTIQ0sQmyX3ysOv6W8zjG96ThH-0-9079e327f18fc5a3fc793f70c71d6316)
2.匹配字符串的结尾
ENDS WITH用于以大小写敏感的方式匹配字符串的结尾。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_102606.jpg?sign=1739375505-I8ZduzqMk5l852fzwqbj2Gf2oSGuJKOO-0-62f0a706d4600683c345055354e6e85e)
返回了Peter,因为其名字以“ter”结尾。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_101603.jpg?sign=1739375505-8Rpz7aaeNh41vRnndMgEJMmuIAs3OEzF-0-8a730f186db1d590165a425b3357c858)
3.字符串包含
CONTAINS用于检查字符串中是否包含某个字符串,它是大小写敏感的,且不关心匹配部分在字符串中的位置。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_102607.jpg?sign=1739375505-JtdJUWcpYo59eXOQ9L7nCS1jv6WZiqUg-0-b9b672d3065de5c023ad29472c1c6451)
返回了Peter,因为其名字包含了“ete”字符串。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_101606.jpg?sign=1739375505-V9ktYmINULZ6P1N7fhdSWTNMrJRM59fw-0-db03b751814be142a4bafc60709296cf)
4.字符串反向匹配
使用NOT关键词可以返回不满足给定字符串匹配要求的结果。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_102608.jpg?sign=1739375505-7TZVWphR0561O3bFp6C6PKAhphaRItHf-0-515adc70950471f051c900227e4e1343)
返回了Peter,因为其名字不以“s”结尾。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P145_101609.jpg?sign=1739375505-ZYWHJLZKLAwOcWfq1UxpEf6pMkCKAcSI-0-71e7586959f52109b31a4f8441c7e179)
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=1739375505-I3ztE8PL46F5PZEU9Dm2cgtzQUzyqnHy-0-1e6d550b2e1e46d6f1989956fd335b6b)
返回了Tobias,因为其名字以“Tob”开始。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P145_101612.jpg?sign=1739375505-bcQdvkCtiRexrIh7Czi1sQoKs3urxfw3-0-a0eeba17423979095c60ba07359271e1)
2.正则表达式中的转义字符
如果需要在正则表达式中插入斜杠,则需要使用转义字符。
注意:字符串中的反斜杠也需要转义。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P145_102610.jpg?sign=1739375505-tlXhFlRIR4jqurB80LxhnCbKE6aE0dr1-0-ddb85b69e709b88b71d5ee956ca19e3a)
返回了Tobias,因为其地址在“Sweden/Malmo”。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_89320.jpg?sign=1739375505-yN5Z1gQpQ7VdMgRjj9iCf299oqwnmWHG-0-0009edbb46fcaff255c43c20c0f922bd)
3.正则表达式的非大小写敏感
在正则表达式前面加入“(?i)”之后,整个正则表达式将变成非大小写敏感。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_102611.jpg?sign=1739375505-fyt4X2I6TgT2tlxK6nhxPgINu26VTwnX-0-a942c08d4d23e466fa0029addd168161)
返回了Andres,因为其名字在不考虑大小写的情况下以“ANDR”开始。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_101616.jpg?sign=1739375505-3DPx3fYmV9zrAO38wmUZWb3KAlm2la0P-0-9b8dcdcb412912c1927bc48ab2e32a34)
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=1739375505-iIvOF3fNscbkgkKInealATrPpBNhGrRj-0-3590e2ab1a98257896f31814e74e5a0b)
结果将返回有外向关系指向Tobias的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_101618.jpg?sign=1739375505-SEsNvrnlAIozZukYplfo6TgrevOHiRDA-0-ec614dd79d89eeb4f8aad8305dd75b18)
2.模式中的NOT过滤
NOT可用于排除某个模式。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_102613.jpg?sign=1739375505-ZHRXysYhNNuAEw0u77q3wjMM7RU8DWgX-0-24853bc98f374920bd3cbfb4eeb7eec1)
结果将返回没有外向关系指向Peter的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_101621.jpg?sign=1739375505-bj5XFLhCnr0KF1QZ5AOw1BgQJjDYIotw-0-2868bcd5ca9b694f0d4daaca730872ac)
3.模式中的属性过滤
可以在模式中添加属性来过滤结果。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_102614.jpg?sign=1739375505-9eiz6EssOax7iKkTGCZFshCQfuOvf0f2-0-91a25e23e08cec141816d241910caf77)
结果将返回与节点Tobias有KNOWS关系的所有节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_101624.jpg?sign=1739375505-VHVDtZXvy8DHFyfbKpe2ekJzWQfWO41U-0-3480f6d559dbcc623154d2eeab753cd1)
4.关系类型过滤
可以在MATCH模式中添加关系类型,但有时候希望在类型过滤上具有丰富的功能。这时,可以将类型与其他进行比较。例如,下面是一个对关系类型与一个正则表达式进行比较的例子。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_102615.jpg?sign=1739375505-7xkn64mhQF9OMADpMV40kvd3UovLbrGa-0-2c100e553f479ae1a9f032207eb696e2)
该查询将返回与Andres节点以“K”开始的所有关系。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_101627.jpg?sign=1739375505-3G44w52NnJGUffQd9scNp7ExW5duSVD1-0-9bea8ba80b2c98ac3771ac4b956181dc)
5.在WHERE中使用简单存在子查询
可以在内部MATCH子句中使用从外部引入的变量,如以下示例所示:
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_102616.jpg?sign=1739375505-5OBxMbkKxnq4jHYRryofCI8vFtBoiveO-0-5978a0923b4f035d20e9a2770f6e16cc)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_101630.jpg?sign=1739375505-pO3W8B1nbKrD21nHGEXFFwIbLm9XyKKZ-0-34a85244849fdf66e72229047e48e52e)
6.嵌套存在子查询
存在子查询可以嵌套,如下例所示。嵌套也会影响范围。这意味着可以从子查询内部访问所有变量,这些变量要么在外部范围内,要么在同一个子查询中定义。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_102617.jpg?sign=1739375505-CfhStxnzb31iwuQVE9mDG9cqKalGtbFp-0-758fc1e3da58efde044ae42e90cc691b)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_101633.jpg?sign=1739375505-JQkxcKqrk02ptcp8g1IDAeNLLekhD1Jr-0-f1a45079b0b68b45b8bcd74d7aaeec37)
3.3.3.5 列表
IN运算符:可以使用IN运算符检查列表中是否存在某个元素。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_102618.jpg?sign=1739375505-mrS8sZDkMwciLD4s9SGMxmEXROPRlxCa-0-42f8b086e3bee45d7c0cfc0fcaa77943)
以上查询将检查字符串列表中是否存在某个属性。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_101636.jpg?sign=1739375505-HqGrDxR2BGq1fcOBEpC505CcFn4eEB3i-0-97d1826e903cf81113a6b291dd7fcca5)
3.3.3.6 不存在的属性和值
如果属性不存在,对它的判断默认返回false。对于不存在的属性值则当作null,在下面例子中,对于没有belt属性的节点的比较将返回false。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_102619.jpg?sign=1739375505-IDZkCoPnlpQ2UFCDMcbUWOs1y8BcDXBu-0-c54f4188a1022daa5a2e66da7e2086bb)
结果将仅返回belt为white的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_101639.jpg?sign=1739375505-k8t8fPJ5uHwHaIYCBBOsygaWBdvGQsNs-0-6c29ee76d63e310ef301f2b17f0782c9)
1.属性不存在默认为true的情况
通过如下查询语句可以实现:如果要比较的属性存在,则可以与期望的值进行比较;如果不存在(IS NULL),则默认值为true。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_102620.jpg?sign=1739375505-48TFMenrnUfnC4GGpI2puI1Wo9o92BVg-0-ca021bd38134a27f4d05033bdc6080ea)
结果将返回满足belt属性值为white和不存在belt属性的所有节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_101642.jpg?sign=1739375505-4jHoGeyVPpvKMiCtIm0vwUZnGuqLTLiQ-0-8c501e8a2f91343cb98ccacd78a68a5f)
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=1739375505-ZkzRtL0zv3BmlxGk0FGRbjh2UXTqd7A7-0-07fa7a760fa5de9314a078a197f2e545)
结果将返回name属性值为Peter的且不存在belt属性的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_101645.jpg?sign=1739375505-P3Y0sfQrtW3X0t40PnZOXYXkIloRl6Ms-0-68974c70b26e3bef69b3cf7bec2dd62e)
3.3.3.7 使用范围
1.简单范围
可以使用不等运算符<、>=和>检查某个元素是否在指定的范围。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_102622.jpg?sign=1739375505-kCR04p5YeK8lsRqHwuyzyqPPDvNVLTt2-0-ccb6bef4b7fa844c5e1100eca38e45ce)
结果将返回节点的name属性值大于或等于Peter的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_101648.jpg?sign=1739375505-uvkpRGtf7vFZGtpYJaJaZgSnzYJrP0ZJ-0-fba1d59f4c5cc43d4339091fb6015e87)
2.范围的组合
可以将多个不等式组合成一个范围。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_102623.jpg?sign=1739375505-5My4Q6rgPL1PipeYgkSMQcNq1e8PSHuB-0-ea94fef34bab99c470ef7a4ead55c61a)
结果将返回name属性值介于Andres和Tobias之间的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P151_101650.jpg?sign=1739375505-vKU0VHmpmq04YJ56Vuu4rMLRhoYoCX9q-0-c71a76d3bf991d3a50da82f87b870c73)