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。我在这里做错了什么?语法对我来说很好。
答案 0 :(得分:2)
pattern comprehension始终会返回一个列表,即使该列表为空。
因此,以下内容永远不会等同于false
或NULL
:
[(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)
这里发生了两件事。请注意Cybersam的答案,因为它与内部的模式理解有关。
但是,更大的问题是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}参数)。
如果您确实确实需要模式理解,请遵循Cybersam的建议,并确保您正在测试由理解得出的列表是空还是非空。