0

我刚刚看到(这里:http ://docs.neo4j.org/chunked/1.9/deprecations.html )!用于 Cypher 属性表达式的运算符将随着 Neo4j 2.0 的发布而被弃用。所以我去重新制定我现有的 Cypher 查询并遇到以下问题。

1.9 查询: START n=node(*) WHERE NOT "NO_FACET" in n.uniqueLabels! RETURN n limit 2;

我得到的是:在所有节点上都没有“uniqueLabels”属性的节点,或者具有此属性但不包含“NO_FACET”值的节点。

上面链接的页面说通过做一个检查来规避这样的表达has(n.uniqueLabels" AND NOT "NO_FACET" IN n.uniqueLabels。该查询有效,但显然不是我想要的(我还想要返回根本没有该属性的节点)。提议的规避看起来像是一个懒惰的 AND 评估,这对我来说很好。所以我这样做了:

START n=node(*) WHERE NOT (has(n.uniqueLabels) AND "NO_FACET" in n.uniqueLabels) RETURN n limit 2;

但是在这里我得到一个错误: ==> EntityNotFoundException: The property 'uniqueLabels' does not exist on Node[0] 所以评估毕竟没有那么懒惰?奇怪的是,这个查询有效:

START n=node(*) WHERE has(n.uniqueLabels) AND "NO_FACET" in n.uniqueLabels RETURN n limit 2;

当然,它只是给了我与我想要的完全相反的东西。

实际上,如果没有这样的运算符,我可以得到我想要的:

START n=node(*) WHERE NOT has(n.uniqueLabels) OR (has(n.uniqueLabels) AND NOT "NO_FACET" in n.uniqueLabels) RETURN n limit 2;

但我不确定这是否是弃用操作员时的预期方式。所以问题是我是否错过了正确的方法,或者 AND 的行为与括号外的 NOT 结合可能是一个错误?

顺便说一句:现在有没有人为什么!运营商一开始就被弃用了?我喜欢 ;-)

感谢您的阅读和最诚挚的问候!

4

1 回答 1

0

我相信这可能是由于 NOT 如何评估其中的表达式造成的。它可能不会短路 AND 表达式,这将导致它不评估第二个表达式。

一种解决方案是德摩根定律(破坏 CS 101)。你的查询会变成这样:

START n=node(*) 
WHERE NOT(has(n.uniqueLabels)) OR NOT("NO_FACET" in n.uniqueLabels)) 
RETURN n limit 2;

我不是 100% 确定为什么不推荐使用这个运算符,它可能与使 Cypher 语言关键字更符合 SQL 之类的东西有关,但你的情况似乎更像是他们系统中的一个错误,因为表达式应该短路在 NOT 语句中的 AND 上。

于 2013-07-19T10:35:19.117 回答