neo4j - 为一组节点创建每两个节点之间的关系
问题描述
我在neo4j中创建了很多节点,这些节点的属性都是一样的,都有user_id和item_id,使用的代码如下:
LOAD CSV WITH HEADERS FROM 'file://data.csv' AS row
CREATE (main:Main_table {USER_ID: row.user_id,
ITEM_ID: row.item_id}
)
CREATE INDEX ON :Main_table(USER_ID);
CREATE INDEX ON :Main_table(ITEM_ID);
现在我想在具有相同 user_id 或 item_id 的节点之间创建关系。例如,如果节点 A、B 和 C 的 USER_ID 相同,我想创建(A)-[:EDGE]->(B)
,(A)-[:EDGE]->(C)
和(B)-[:EDGE]->(C)
. 为了实现这个目标,我尝试了以下代码:
MATCH (a:Main_table),(b:Main_table)
WHERE a.USER_ID = b.USER_ID
CREATE (a)-[:USER_EDGE]->(b);
MATCH (a:Main_table),(b:Main_table)
WHERE a.ITEM_ID = b.ITEM_ID
CREATE (a)-[:ITEM_EDGE]->(b);
但是由于数据量很大(3000000个节点,100000个用户),这个过程很慢,怎么才能快速完成这个过程呢?任何帮助将不胜感激!
解决方案
您的查询导致笛卡尔积,并且 Cypher 规划器不使用索引来优化涉及节点属性比较的节点查找。
像这样的查询(而不是您的USER_EDGE
查询)可能会更快,因为它不会导致笛卡尔积:
MATCH (a:Main_table)
WITH a.USER_ID AS id, COLLECT(a) AS mains
UNWIND mains AS a
UNWIND mains AS b
WITH a, b
WHERE ID(a) < ID(b)
MERGE (a)-[:USER_EDGE]->(b)
该查询使用聚合函数 COLLECT
来收集具有相同USER_ID
值的节点,并使用ID(a) < ID(b)
测试来确保a
和b
不是相同的节点,并防止重复关系(在相反的方向上)。
推荐阅读
- python - 是否可以更改 pyplot 上的刻度频率与数据集长度无关并缩放?
- arm - 无法通过 SSH 连接到运行 dropbear sshd 的 QEMU 虚拟机
- java - 如何使用二维按钮数组刷新面板?
- javascript - 如何在 D3 Js 中将 y 轴(yDomain)值设置为最大值
- r - 从 R 中的数据框创建相关矩阵
- reactjs - 在同一个文件中同时添加命名组件和默认组件是否合法?
- r - 使用 pacman 在 Ubuntu 中安装 R 包时出现依赖项错误
- python - sqlite python - 从txt文件将记录读入表
- python - 如何从两个列表中创建堆叠条形图:考虑一个是集群,另一个是标志
- c# - 如果特定值在行内,则更改行中的背景颜色