首页 > 解决方案 > 在 Neo4j 中收集非常慢

问题描述

如何使用 2.2B 节点上的集合来汇总一对带有标签的 ID?我想滚动两个 uid 的平面列表,其中的标签将它们连接起来而不重复。我在 neo4j 中有一个图表,由 10 个 ID、9 个连接 ID 和 1 个第一方 ID 组成。

我正在尝试创建一个查询,对于通过一个或多个连接 ID 连接的每一对第一方 ID,我有一个第三方 ID 正在连接它们的列表。

现在我有一个查询如下:

Match (u:User)-[]->(id)
match (id)<-[]-(u2:User)
where u <> u2 and ID(u) < ID(u2)
return u.uid,u2.uid,labels(id)
limit 100

它返回一个 u, u1, 标签列表,看起来像

u|u2|labels
uid1|uid2|["label1"] 
uid2|uid3|["label2"]
uid1|uid2|["label2"]

我想做的是将列表汇总到一个集合中,例如

Match (u:User)-[]->(id)
match (id)<-[]-(u2:User)
where u <> u2 and ID(u) < ID(u2)
return u.uid,u2.uid,collect(labels(id))
limit 100

但它非常慢并且冻结了我的浏览器。我正在使用 244 GB EC2 上的 163 GB 数据集并给出

dbms.memory.heap.initial_size=150g
dbms.memory.heap.max_size=150g
dbms.memory.pagecache.size=60g

标签: neo4jcollect

解决方案


问题是 collect() 聚合将需要首先实现所有结果,因此 LIMIT 最后将只是一个过滤器,这不适用于您的数据库大小。

由于您的限制应该仅适用于具有该模式的不同节点对(无论它们之间有多少公共节点),因此最好在使用后将 LIMIT 向上移动并找到它们之间的公共节点(及其标签)限量100套。

试试这个:

MATCH (u:User)-->()<--(u2:User)
WHERE ID(u) < ID(u2)
WITH DISTINCT u, u2
LIMIT 100
RETURN u, u2, [(u)-->(id)<--(u2) | labels(id)] as idLabels

我们最后使用了模式理解,但是您可以轻松地完成 MATCH 和 collect() 。


推荐阅读