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。我也运行了count
,min
和max
聚合,它们都符合预期(分别为100001,0,100000)。
我的代码有问题吗?或者在Neo浏览器中存在某种限制?或其他什么......?
如果我运行相同的查询但只创建范围为10000:
...
WITH range(0, 10000) AS list, p, e
...
我从聚合中获得预期值。
答案 0 :(得分:4)
这似乎是无符号32位integer overflow的结果。
如果您更改了查询以返回总和,那么您也会看到错误的结果:
MATCH (:PERSON)-[a:ATTENDED]->(:EVENT)
RETURN SUM(a.val);
而不是5000050000
(50000*100001
的结果),返回的总和大约为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);
答案 1 :(得分:1)
Avg和sum有一个整数溢出的错误,因为avg在这里解决了:https://github.com/neo4j/neo4j/pull/5707
您可以快速重现您的问题:
try {
$loader = new FileUploader ($destination);
$loader->upload();
$loader->getMessages();
} catch(Exception $e){
echo $e->getMessages();
}
和cybersam的建议:
UNWIND range(0, 100000) as x
return min(x),max(x),count(x),sum(x),avg(x),sum(x) / count(x)