密码查询条件始终返回true

时间:2018-06-26 14:59:57

标签: neo4j cypher

MATCH (c:OBJ {dummy:false})
where [{param} is null or [(c)-[]->(p:PRO {dummy:false}) WHERE p.val ={param} | true ] ]
return c

我有一个很大的查询,其中有这个简单的部分。但是

[{param} is null or [(c)-[]->(p:PRO {dummy:false}) WHERE  p.val = {param} | true] ]
即使p.val ={param}为false,

part始终返回true。我在这里做错了什么?语法对我来说很好。

2 个答案:

答案 0 :(得分:2)

pattern comprehension始终会返回一个列表,即使该列表为空。

因此,以下内容永远不会等同于falseNULL

[(c)-[]->(p:PRO {dummy:false}) WHERE  p.val = {param} | true]

此查询(用于测试内部理解结果的大小)可能对您有用:

MATCH (c:OBJ {dummy:false})
WHERE [$param IS NULL or SIZE([(c)-->(p:PRO {dummy:false}) WHERE p.val = $param | true]) > 0 ]
RETURN c

答案 1 :(得分:1)

这里发生了两件事。请注意Cyber​​sam的答案,因为它与内部的模式理解有关。

但是,更大的问题是WHERE子句最终将评估一个列表,而不是布尔值!

通过在整个WHERE子句中使用方括号,这意味着您正在创建列表,并且列表内容将在其中。内部的内容将评估为布尔值,因此这意味着两种结果:

WHERE [true]

WHERE [false]

在这两种情况下,都不是布尔值,而是单元素列表,列表中唯一的元素是布尔值!

在这样的列表上使用WHERE总是会评估为true。无论列表中有什么。无论列表中有多少个元素。无论列表是否为空。如果列表本身存在,它将被评估为true,并且WHERE子句成功。

因此,要解决所有这些问题,请勿使用方括号作为分隔布尔逻辑的某种方法。仅在您确实需要括号时才使用括号:

MATCH (c:OBJ {dummy:false})
WHERE ( {param} is null or (c)-->(:PRO {dummy:false, val:{param}}) )
RETURN c

在上面,并不需要使用WHERE子句时使用的括号,但是您可以根据需要使用它们。

这也应该是表达所需谓词的更好方法。在这种情况下,我们根本不需要模式理解。足以说明我们要么需要将{param}参数设置为null,要么必须存在该模式(其中一个属性是{param}参数)。

如果您确实确实需要模式理解,请遵循Cyber​​sam的建议,并确保您正在测试由理解得出的列表是空还是非空。