为什么我的 WHERE 子句不起作用?
当 WHERE 子句似乎不起作用时,这可能会令人沮丧。您可以使用以下方法来找出问题所在。
检查在 OPTIONAL MATCH 之后是否有 WHERE 子句
WHERE 子句不能单独使用,它们总是与 MATCH、WITH 或 OPTIONAL MATCH 配对,正是这种配对定义了 WHERE 子句在计算为 false 时的行为。
WITH … WHERE
和 MATCH … 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 WITH
、ENDS WITH
或 CONTAINS
查询也可以帮助测试您对属性值的假设。
属性键中的额外空格比较少见,但可能发生,例如在从格式错误的文件导入数据时。
例如,如果我们尝试导入具有以下标题的 csv 文件
nickName, firstName,lastName
在 firstName
之前有一些前导空格,在 lastName
之后有一些尾随空格。导入后,属性键本身将包含前导和尾随空格,因此实际属性键变为 "nickName"、" firstName" 和 "lastName ",如果未检测到,可能会很快成为混乱的来源。
此页面是否有帮助?