知识库

为什么我的 WHERE 子句不起作用?

当 WHERE 子句似乎不起作用时,可能会令人沮丧。您可以使用以下方法找出问题所在。

检查 OPTIONAL MATCH 后的 WHERE 子句

WHERE 子句不能单独使用,它们总是与 MATCH、WITH 或 OPTIONAL MATCH 配对使用,正是这种配对定义了当 WHERE 子句评估为 false 时的行为。

WITH …​ WHEREMATCH …​ WHERE 将 WHERE 子句应用于所有结果行,这通常是大多数用户期望 WHERE 的行为方式,即当 WHERE 评估为 false 时移除行。

然而,OPTIONAL MATCH …​ WHERE 的行为方式不同,因为 OPTIONAL MATCH 从不移除行。在使用 OPTIONAL MATCH 时,如果给定模式不匹配,或者其 WHERE 子句评估为 false,则模式中新引入的变量对于给定行将变为 null。行永远不会被移除,现有变量保持不变,这可能会给人一种 WHERE 子句完全不起作用的印象,而真正的问题是它被应用到了错误的地方。

MATCH (m:Movie)
OPTIONAL MATCH (m)<-[:WORKED_ON]-(a:Animator)
WHERE m.releaseYear > 1999 AND a IS NOT NULL
RETURN m, collect(a) as animators

在上面的示例中,这看起来像是一个查询,用于获取 1999 年之后上映的电影以及电影中动画师的制作情况,但这不正确。WHERE 子句只会影响 OPTIONAL MATCH,因此所有电影都将被返回,没有任何电影会被过滤掉,但动画师集合只会填充 1999 年之后上映的电影。

要修复该查询,我们需要将 WHERE 移动到其他位置,使其与 MATCH 或 WITH 相关联,以便按要求过滤行。

MATCH (m:Movie)
OPTIONAL MATCH (m)<-[:WORKED_ON]-(a:Animator)
WITH m, a
WHERE m.releaseYear > 1999 AND a IS NOT NULL
RETURN m, collect(a) as animators

检查 WHERE 子句中的拼写错误或大小写不匹配

拼写错误和错别字很容易导致 WHERE 子句失效,这也包括大小写不匹配。

节点标签、关系类型、变量以及属性键和值都是区分大小写的,因此请确保您在大小写方面保持一致和正确。

MATCH (m:Movie)
WHERE NOT (m)<-[:worked_on]-(a:animator) AND m.ReleaseYear > 1999
RETURN m

上述查询没有拼写错误,但其关系类型、节点标签和属性键的大小写与实际图数据中的不同,这将严重影响 WHERE 子句的判断。

检查假定的数值属性是否实际上是字符串

在数值比较或匹配似乎失败的情况下,确保您要比较的属性实际上是数字会有所帮助。

在文本结果视图中,字符串值会带有引号,而数值则不会。

在导入过程中要特别注意,尤其是 CSV 导入,因为所有值都会被解释为字符串。您需要使用 toInteger()toFloat() 将字符串转换为数值,以避免此问题。

检查属性键和值中是否存在前导或尾随空格

属性中的前导或尾随空格可能导致 WHERE 子句看起来不起作用,这通常是图数据本身的问题,而非查询本身的问题。

MATCH (m:Movie)<-[:ACTED_IN]-(p:Person)
WHERE p.name = 'Keanu Reeves'
RETURN m

上述查询看起来没有问题,甚至可能完全正确。但是,如果节点的 name 属性实际上是带有尾随空格的“Keanu Reeves ”,则查询将不起作用。

通常最好仔细检查节点和关系上的预期字符串值,以查看是否是意外的空格导致问题。如果使用 Neo4j 浏览器,文本结果视图通常是轻松检测额外空格的最佳方式。使用 STARTS WITHENDS WITHCONTAINS 进行查询也有助于测试您对属性值的假设。

属性键中出现额外空格的情况比较少见,但也有可能发生,例如从格式不佳的文件导入数据时。

例如,如果我们尝试导入一个带有以下标题的 CSV 文件

nickName, firstName,lastName

firstName 前有一些前导空格,在 lastName 后有一些尾随空格。导入后,属性键本身将包含前导和尾随空格,因此实际的属性键变为“nickName”、“ firstName”和“lastName ”,如果未被检测到,可能会迅速成为混淆的来源。

© . All rights reserved.