Neo4j除以零(0)

Neo4j除以零(0),neo4j,cypher,division,divide-by-zero,Neo4j,Cypher,Division,Divide By Zero,在neo4j中,我提出了质疑 MATCH (n)-[t:x{x:"1a"}]->() WHERE n.a > 1 OR n.b > 1 AND toFloat(n.a) / (n.a+n.b) * 100 < 90 RETURN DISTINCT n, toFloat(n.a) / (n.a + n.b) * 100 ORDER BY toFloat(n.a) / (n.a + n.b) * 100 DESC LIMIT 10 MATCH(n)-[t:x{x:1a}]-

在neo4j中,我提出了质疑

MATCH (n)-[t:x{x:"1a"}]->()
WHERE n.a > 1 OR n.b > 1 AND toFloat(n.a) / (n.a+n.b) * 100 < 90
RETURN DISTINCT n, toFloat(n.a) / (n.a + n.b) * 100
ORDER BY toFloat(n.a) / (n.a + n.b) * 100 DESC
LIMIT 10
MATCH(n)-[t:x{x:1a}]->()
其中n.a>1或n.b>1,且toFloat(n.a)/(n.a+n.b)*100<90
返回不同的n,toFloat(n.a)/(n.a+n.b)*100
托福莱特订购(不适用)/(不适用+不适用)*100说明
限制10
但是我得到了零的
/错误


因为我声明n.a或n.b中的一个应该是1,如果两者都为零,它应该跳过该行,我不应该得到这个错误。这看起来像是Neo4j中的一个逻辑问题。当我从WHERE子句中删除
和toFloat(n.a)/(n.a+n.b)*100<90
时没有问题。但我只希望结果低于90。如何克服这个问题?

n.a
n.b
中的任何一个都可以是负的吗?我能够用以下方法重现这一点:

WITH -2 AS na, 2 AS nb
WHERE (na > 1 OR nb > 1) AND toFloat(na)/(na+nb)*100 < 90
RETURN na, nb

我得到:零行。

似乎第二个条件,
toFloat(na)/(na+nb)*100<90
,在第一个条件之前进行了测试。查看此执行计划中的
过滤器(1)
运算符:

+--------------+---------------+------+--------+--------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|     Operator | EstimatedRows | Rows | DbHits |                                            Identifiers |                                                                                                                                                                                      Other |
+--------------+---------------+------+--------+--------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|   Projection |             1 |    3 |      0 | anon[111], anon[138], n, toFloat(n.a)/(n.a + n.b)* 100 |                                                                                                                                                                       anon[111]; anon[138] |
|          Top |             1 |    3 |      0 |                                   anon[111], anon[138] |                                                                                                                                                                             {  AUTOINT6};  |
|     Distinct |             0 |    3 |     24 |                                   anon[111], anon[138] |                                                                                                                                                                       anon[111], anon[138] |
|    Filter(0) |             0 |    3 |      6 |                                         anon[29], n, t |                                                                                                                                                                     t.x == {  AUTOSTRING0} |
|  Expand(All) |             1 |    3 |      6 |                                         anon[29], n, t |                                                                                                                                                                          (  n@7)-[t:x]->() |
|    Filter(1) |             1 |    3 |     34 |                                                      n | (Ors(List(n@7.a > {  AUTOINT1}, Multiply(Divide(ToFloatFunction(  n@7.a),Add(  n@7.a,  n@7.b)),{  AUTOINT3}) < {  AUTOINT4})) AND Ors(List(  n@7.a > {  AUTOINT1},   n.b > {  AUTOINT2}))) |
| AllNodesScan |             4 |    4 |      5 |                                                      n |                                                                                                                                                                                            |
+--------------+---------------+------+--------+--------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+--------------+---------------+------+--------+--------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|运算符| EstimatedRows |行|数据命中|标识符|其他|
+--------------+---------------+------+--------+--------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|投影| 1 | 3 | 0 | anon[111],anon[138],n,toFloat(n.a)/(n.a+n.b)*100 | anon[111];阿农[138]|
|Top | 1 | 3 | 0 | anon[111],anon[138]|{AUTOINT6}|
|不同的| 0 | 3 | 24 | anon[111],anon[138]| anon[111],anon[138]|
|滤波器(0)| 0 | 3 | 6 | anon[29],n,t | t.x=={AUTOSTRING0}|
|展开(全部)| 1 | 3 | 6 | anon[29],n,t |(n@7)-[t:x]->()|
|过滤器(1)| 1 | 3 | 34 | n |(Ors)(列表(n@7.a>{AUTOINT1},乘(除)(ToFloatFunction(n@7.a),加入(n@7.a,  n@7.b)),{AUTOINT3})<{AUTOINT4})和Ors(列表(n@7.a>{AUTOINT1},n.b>{AUTOINT2})|
|AllNodesScan | 4 | 4 | 5 | n ||
+--------------+---------------+------+--------+--------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
您可以通过强制将筛选器拆分为两个子句来解决此问题

MATCH (n)-[t:x { x:"1a" }]->()
WHERE n.a > 1 OR n.b > 1
WITH n
WHERE toFloat(n.a) / (n.a + n.b) * 100 < 90
RETURN DISTINCT n, toFloat(n.a) / (n.a + n.b) * 100
ORDER BY toFloat(n.a) / (n.a + n.b) * 100 DESC 
LIMIT 10
MATCH(n)-[t:x{x:1a}]->()
其中n.a>1或n.b>1
与n
其中toFloat(n.a)/(n.a+n.b)*100<90
返回不同的n,toFloat(n.a)/(n.a+n.b)*100
托福莱特订购(不适用)/(不适用+不适用)*100说明
限制10
我发现这种行为令人惊讶,但我认为执行引擎以这种方式重新排列过滤器并没有错。可能存在这样的假设,即在第一个声明的条件失败时,该条件将尽早放弃,但Cypher恰恰是:声明性的。因此,我们表达的是“什么”,而不是“如何”,根据“什么”
A和B
相当于
B和A

这是查询和示例图,您可以检查它是否转换为实际数据:

用括号括起
n.a>1或n.b>1
。@NicoleWhite它不起作用,结果又是一样的。不,它们不能是负数。你能发布示例数据以便重现错误吗?我想是
n.a=0,n.b=0
的情况打破了(“如果两者都为零,则应跳过”)。如果是这样,下面是一个示例图:。我已经回答了我认为正在发生的事情,但是我今天还没有喝咖啡,所以我很想听听你的想法。@NicoleWhite我不能分享它,对不起,但是如果你愿意,我想你可以很容易地复制它。谢谢:)@jjaderberg奇怪。n.a=0和n.b=0时,我无法复制。是的,它正在工作!非常感谢您的详细回答。
MATCH (n)-[t:x { x:"1a" }]->()
WHERE n.a > 1 OR n.b > 1
WITH n
WHERE toFloat(n.a) / (n.a + n.b) * 100 < 90
RETURN DISTINCT n, toFloat(n.a) / (n.a + n.b) * 100
ORDER BY toFloat(n.a) / (n.a + n.b) * 100 DESC 
LIMIT 10