![精通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=1739025193-ZqEGRYl8l91h982ZmemJ33dWlejiCRnk-0-cca426eb4cf89b130b6b82ce0bc58e7d)
图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=1739025193-XpYYgtS3Sfkqycx0hfVhzyCjg8C1Tsn7-0-3486c0c14b2ce6122155796a427a18f4)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P141_101583.jpg?sign=1739025193-aYEdHCKhy023HlRV6nwRGnE4Wj0NmaWn-0-bb09d1c7143956348526dcb9ac4bb5c7)
2.节点标签的过滤
可以在WHERE中类似使用WHERE n:foo写入标签断言来过滤节点。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P141_102599.jpg?sign=1739025193-hy3Pn2F3FFyKgC3u3cp1ztrajXMypYf1-0-2af7a25c6af83a0e49b849097d3d6e0f)
将返回Andres节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P141_101586.jpg?sign=1739025193-vNwhaf2mEcdMg2Wxzj9hq0fMA3lI1ruq-0-893ba540c22934b09a7dece6d0afe67d)
提示:提示:如果要查询不包含某个标签的其他所有节点的反向查询,可在WHERE后加NOT。
3.节点属性的过滤
可以在WHERE语句中对节点的属性进行过滤。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_102600.jpg?sign=1739025193-2UffxUFHdAQXCwjw5REHg9PdgKFcKv7C-0-c21041e95bf7d7e1262a598040ad9c01)
返回了Tobias节点,因为其年龄小于30。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_101589.jpg?sign=1739025193-eDxyHExo3mQjfM3cavRAftmMlMUpCGDQ-0-f570f2afe48755711d010b07367cffa0)
4.关系属性的过滤
要对关系的属性进行过滤,可在WHERE中添加如下关键词:
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_102601.jpg?sign=1739025193-q2cpBYr2P0aCbO53aFFASBT5ZPzC12Z8-0-6efe2a5a46a75ecfb557763f31eaab97)
返回了Peter,因为Andres自1999年就认识他了。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_101592.jpg?sign=1739025193-Po7CY4NpFnoBCCnVvqOsq8CUuQF7Fii3-0-fd00231f54c5aa31cdb7e40acd8d83b4)
5.动态节点属性过滤
以方括号语法的形式使用动态计算的值来过滤属性。
参数:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_102602.jpg?sign=1739025193-gtr9754waZ0mDQaz6mQImPASQBZcdYUW-0-146a99cda7ef6f966307de477aad1cd3)
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P142_89134.jpg?sign=1739025193-GyFPtv1mHOwOclsn1QrqXTuYrqrM0Uhj-0-cc6b4229569165ba5a61293af0f9ae7c)
返回了“Tobias”,因为他的年龄小于30。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_101595.jpg?sign=1739025193-SEUAQXs35d99ecKtgUVTtel6TlPPxDDj-0-73cc59636a9be592dc82b94b27309871)
6.属性存在性检查
可以使用exists()检查节点或者关系的某个属性是否存在。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_102604.jpg?sign=1739025193-GXd1FkizhlAanEpGrbRn7AxXpIf8ipbL-0-d6cc88d8839378d0e35d6c0dc3932b5c)
返回了Andres,因为只有belt属性。
提示:提示:has()函数已被移除,并被exists()替代了。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_101597.jpg?sign=1739025193-UpNoCw6E0DPPVDifRfpCAPRiNuYlmJNN-0-47c2538616c2d1d7bc7bf8dccf7fb24b)
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=1739025193-gehNwVw25NHwmN02aO0dtUCzvxZPjvuU-0-0e4dc296df03811288faaa07ec762451)
返回了Peter,因为其名字以“Pet”开始。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P143_101600.jpg?sign=1739025193-13rKSzkHQegIi5bCZKCqZWeelaAC6rwz-0-c98da420eba904cea5a294048c10af55)
2.匹配字符串的结尾
ENDS WITH用于以大小写敏感的方式匹配字符串的结尾。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_102606.jpg?sign=1739025193-yLighl2o6zKWzknltV2UzZ0VLHZwKUb6-0-bb9b8e594af03cc7d41f9b8b6712902e)
返回了Peter,因为其名字以“ter”结尾。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_101603.jpg?sign=1739025193-q6f19a0j8fxoTvX7F4zi8mCKljcWGDdP-0-313b8e660d3733c86aefceabbf85f08b)
3.字符串包含
CONTAINS用于检查字符串中是否包含某个字符串,它是大小写敏感的,且不关心匹配部分在字符串中的位置。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_102607.jpg?sign=1739025193-MQECU3zm5KNKxVTs3KAwCt54gmssh6LO-0-3d8515acd351a7eebbe710c3e27f0bbb)
返回了Peter,因为其名字包含了“ete”字符串。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_101606.jpg?sign=1739025193-QJftohI7xB1Egyg18xXg48DOtXCdvXlc-0-df4f7056c2c36a1784223f3188e692f8)
4.字符串反向匹配
使用NOT关键词可以返回不满足给定字符串匹配要求的结果。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P144_102608.jpg?sign=1739025193-TxWv4GRnMhPP2UL777HdtTIxjmmziC43-0-9987cc69e96a5bd7ee11b91750addadb)
返回了Peter,因为其名字不以“s”结尾。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P145_101609.jpg?sign=1739025193-aq2f0Sda2bmEpVfcz0nBwcIIashWxNlR-0-4c406bca7114e7fc650473f090ae062b)
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=1739025193-wc6JuXhu2UfkF30k1nNRPGo8VcEQyG5v-0-aeee4c564117efc50b4f7175dce9c198)
返回了Tobias,因为其名字以“Tob”开始。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P145_101612.jpg?sign=1739025193-j5DXJ2xew5hU7yfeNe9Sd1UPhtmRZptY-0-c56f7f959090f4fd05ddca6841c0df07)
2.正则表达式中的转义字符
如果需要在正则表达式中插入斜杠,则需要使用转义字符。
注意:字符串中的反斜杠也需要转义。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P145_102610.jpg?sign=1739025193-qe4CXuaArkvfUYh2DYLAQbi3QMfeUoRH-0-3f86452b78f7c3a1a0106509274c5749)
返回了Tobias,因为其地址在“Sweden/Malmo”。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_89320.jpg?sign=1739025193-UtEu4x2dlYXTNdL3S5V7kAguR2qu1yic-0-4fe3dad0fb8ff10e6264e5da338d0c50)
3.正则表达式的非大小写敏感
在正则表达式前面加入“(?i)”之后,整个正则表达式将变成非大小写敏感。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_102611.jpg?sign=1739025193-g3RIMoANMfDHlRNAGXX3CCERPzfKrqYR-0-0d3217fdfdb0ce67828ba104719e2cdf)
返回了Andres,因为其名字在不考虑大小写的情况下以“ANDR”开始。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_101616.jpg?sign=1739025193-Se335Jj9mtdiOhvJCqHMuto6lwhO3Dev-0-06c0f6db113d4e2b92b6e2cb76455228)
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=1739025193-VtClqjRkG0IcCnQtigrWuBcou6XG0G02-0-d3b41e1c0fd7bd6ddabb165955021e62)
结果将返回有外向关系指向Tobias的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P146_101618.jpg?sign=1739025193-oLJT5S3xOjVIJCHTdT4om24wQqvpjGyn-0-b8b87be1912da18c9becb294f5fe0a5f)
2.模式中的NOT过滤
NOT可用于排除某个模式。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_102613.jpg?sign=1739025193-zUOsnJ0qvqiRyXKcwJcnGtLqw76uWgCK-0-d3cc0aca57c5eb7e9b74a664d6f833c9)
结果将返回没有外向关系指向Peter的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_101621.jpg?sign=1739025193-6rhxZFlD5iDFmGrOONtTrPGGu2mn7uIr-0-9eed62bac582e7d1fbfa0a6ad7d31b96)
3.模式中的属性过滤
可以在模式中添加属性来过滤结果。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_102614.jpg?sign=1739025193-AEVD3L8yFYZQUcsgvmRyu188lwdB4Y4U-0-0fe0625d4805a47a4af672670d4b55ee)
结果将返回与节点Tobias有KNOWS关系的所有节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_101624.jpg?sign=1739025193-cJ2AG5DHQJlszqT5RQbsfBlDq9tXte8U-0-50c42919e36a25aa8753c02c2992af1e)
4.关系类型过滤
可以在MATCH模式中添加关系类型,但有时候希望在类型过滤上具有丰富的功能。这时,可以将类型与其他进行比较。例如,下面是一个对关系类型与一个正则表达式进行比较的例子。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_102615.jpg?sign=1739025193-me4evgPLUA95Guz6PEe7Pmx8BXqnzo8w-0-19b589d7ab378b32debc21f779aa3c0e)
该查询将返回与Andres节点以“K”开始的所有关系。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P147_101627.jpg?sign=1739025193-lDhHnFKkUWbA3wHsOoJGHDOgcy3QZw0B-0-6d3bf2d74b5b2d67ca64cf06b631e98a)
5.在WHERE中使用简单存在子查询
可以在内部MATCH子句中使用从外部引入的变量,如以下示例所示:
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_102616.jpg?sign=1739025193-gGoHXpvunK8iJo6PDvRSRIbcDkFZvF0b-0-dc09955d1dfbc0066232922a39e31ae4)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_101630.jpg?sign=1739025193-jPxnRl116ApNcDRURuo6Oe6wFmYZotu9-0-7edf27fc5344fd91a474f0165f061e46)
6.嵌套存在子查询
存在子查询可以嵌套,如下例所示。嵌套也会影响范围。这意味着可以从子查询内部访问所有变量,这些变量要么在外部范围内,要么在同一个子查询中定义。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_102617.jpg?sign=1739025193-7YwAkskvLbeq5GCDbybyLMefb1jUfLE7-0-90d7ff22c9ef6fd2f7e8aa9265be4ae0)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_101633.jpg?sign=1739025193-xR4m3dnV8wo3WpdFxVQu7Ma3xW8BvTqs-0-09e8590b72f6f32a597687f7170a88ad)
3.3.3.5 列表
IN运算符:可以使用IN运算符检查列表中是否存在某个元素。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P148_102618.jpg?sign=1739025193-FnV1bzZcR6wFzmQ7TbjLnvj8tUHL9WDQ-0-99277f3486bf6a5267dd3a423a5ac562)
以上查询将检查字符串列表中是否存在某个属性。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_101636.jpg?sign=1739025193-KqTxXSagToU2Bmg7dEbvu8kAXB109gMv-0-f219411d80195fe854d647aeb397c975)
3.3.3.6 不存在的属性和值
如果属性不存在,对它的判断默认返回false。对于不存在的属性值则当作null,在下面例子中,对于没有belt属性的节点的比较将返回false。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_102619.jpg?sign=1739025193-OUxKJkiyvNqfrJNlc8peMeYawSiFlfMC-0-968c29b1f9d0483c903773609ceb65f3)
结果将仅返回belt为white的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_101639.jpg?sign=1739025193-OjmbHbjfca9DUv9CapQ0sJvvvvdEyqtk-0-b120f0a3f013a8072f70741fe11d8857)
1.属性不存在默认为true的情况
通过如下查询语句可以实现:如果要比较的属性存在,则可以与期望的值进行比较;如果不存在(IS NULL),则默认值为true。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_102620.jpg?sign=1739025193-7ecFp3z3OGwDu52MMslUuVtPPS6sXgeX-0-f28ac91110fd04d02d1d21bb05e11570)
结果将返回满足belt属性值为white和不存在belt属性的所有节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P149_101642.jpg?sign=1739025193-yWZQIb1NtYHEWRk19XmJ1nb1GQ0nkjJU-0-3dfb272f02c8864d7ed3345922b342be)
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=1739025193-Ue6fcNdyXZPwfrv5A2zE4I4iZeLXT4BE-0-cad6cbdfcd9735f29e0cc6947853b8bb)
结果将返回name属性值为Peter的且不存在belt属性的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_101645.jpg?sign=1739025193-sehP9p9GKhrYMf85r0tfsDLQswszMsIw-0-7dea507f719fe9495a8074e295f721a5)
3.3.3.7 使用范围
1.简单范围
可以使用不等运算符<、>=和>检查某个元素是否在指定的范围。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_102622.jpg?sign=1739025193-yUZAtGq18npwQh0cs7Kpepku5SVoAneu-0-2523a5bb979d6862567a5c10ed8a683a)
结果将返回节点的name属性值大于或等于Peter的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_101648.jpg?sign=1739025193-kwgO5Vyl2Iz7sCRZJXhL3iILfHdApv4w-0-519a2993540ad70536e2347afb823231)
2.范围的组合
可以将多个不等式组合成一个范围。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P150_102623.jpg?sign=1739025193-dtWr5ewUlMrznp197mYtXdEVcA8pDWNC-0-aa0d3fcca4f0de4366f12aba054447a5)
结果将返回name属性值介于Andres和Tobias之间的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P151_101650.jpg?sign=1739025193-akYGDCNQSp6FWe1eE97dDQlAezkswm37-0-65ad23ab049f1325e1bbab89bac436e2)