Neo4j浏览器关系限制?

3

Neo在处理大量关系的聚合计算时似乎返回了不正确的值。 注意:我在所有查询中都使用Neo浏览器。

我先创建一些简单的样本数据:

CREATE (p:PERSON)
CREATE (e:EVENT)
WITH range(0, 100000) AS list, p, e
UNWIND list AS val  
CREATE (p)-[:ATTENDED {val: val}]->(e)

然后运行我的聚合:

MATCH (:PERSON)-[a:ATTENDED]->(:EVENT)
RETURN avg(a.val)

我得到的值是7050.7...,而不是预期的50000。我还运行了countminmax聚合函数,它们的结果都如预期一样(分别为100001、0、100000)。
我的代码有问题吗?还是Neo浏览器存在某种限制?或者其他原因...?
注意: 如果我只创建到10000的范围,然后运行相同的查询:
...
WITH range(0, 10000) AS list, p, e
...

我从聚合计算中得到了预期值。

2个回答

4
这似乎是无符号32位整数溢出的结果。
如果您修改了查询以返回总和,则还会看到错误的结果:
MATCH (:PERSON)-[a:ATTENDED]->(:EVENT)
RETURN SUM(a.val);

代替50000*100001的结果5000050000,返回的总和大约为705082704(实际总和取决于导致溢出的值是什么)。

最大的无符号32位整数值是4294967295(或2^32-1)。如果将其加到705082704或其他总和中,你会得到一个接近预期值5000050000的总和。通常情况下,它不会完全等于预期值,因为溢出通常发生在添加数字的"中间"而不是"开始"。

如果你的查询将值转换为浮点数,你将看到预期的结果:

MATCH (:PERSON)-[a:ATTENDED]->(:EVENT)
RETURN AVG(TOFLOAT(a.val))

另外,如果您存储了浮点属性值,原始查询将会起作用:

CREATE (p:PERSON)
CREATE (e:EVENT)
WITH RANGE(0, 100000) AS list, p, e
UNWIND list AS val  
CREATE (p)-[:ATTENDED {val: TOFLOAT(val)}]->(e);

啊...谢谢。这让我很有道理。 - James

1
Avg和sum存在整数溢出的问题,对于avg,此问题已在此处得到解决:https://github.com/neo4j/neo4j/pull/5707 您可以通过以下方式快速重现您的问题:
UNWIND range(0, 100000) as x
return min(x),max(x),count(x),sum(x),avg(x),sum(x) / count(x)

和Cybersam的建议一样:

UNWIND range(0, 100000) as x
with toFloat(x) as x
return min(x),max(x),count(x),sum(x),avg(x),sum(x) / count(x)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接