在 neo4j 中导入多个 csv 的有效方法

Efficient way to import multiple csv's in neo4j

我正在为 CALL 数据集在 neo4j 中创建图形数据库。数据集存储在包含以下列的 csv 文件中:源、目标、时间戳、持续时间。这里 Source 和 Target 是 Person id(数字),Timestamp 是日期时间,持续时间以秒为单位(整数)。

我为我的图表建模,其中人是节点(person_id 作为 属性),调用作为关系(时间和持续时间作为 属性)。 大约有 2,00,000 个节点和大约 7000 万个关系。我有一个单独的 csv 文件,其中包含用于创建节点的人员 ID。我还在 Person id 上添加了唯一性约束。

CREATE CONSTRAINT ON ( person:Person ) ASSERT (person.pid) IS UNIQUE

我不完全理解批量导入的工作原理,所以我写了一个 python 脚本将我的 csv 分成 70 个 csv,其中每个 csv 有 100 万个节点(另存为 calls_0,calls_1, .... calls_69).我主动手动 运行 每次更改文件名的密码查询。它对前几个(大约 10 个)文件运行良好(足够快),但后来我注意到在从一个文件添加关系后,下一个文件的导入速度变慢了。现在导入一个文件需要将近 25 分钟。 有人可以 link 告诉我一个高效简单的方法吗?

这里是密码查询:

:auto USING PERIODIC COMMIT 1000
LOAD CSV WITH HEADERS FROM 'file:///calls/calls_28.csv' AS line
WITH toInteger(line.Source) AS Source, 
datetime(replace(line.Time,' ','T')) AS time,
toInteger(line.Target) AS Target,
toInteger(line.Duration) AS Duration
MATCH (p1:Person {pid: Source})
MATCH (p2:Person {pid: Target})
MERGE (p1)-[rel:CALLS {time: time, duration: Duration}]->(p2)
RETURN count(rel)

我正在使用 Neo4j 4.0.3

您的 MERGE 子句必须检查现有的匹配关系(以避免创建重复项)。如果您在 Person 节点之间添加了 很多 关系,这可能会使 MERGE 子句变慢。

您应该考虑使用 CREATE 代替 MERGE 是否安全。

如果使用每个节点的 ID 导出匹配项然后创建关系会更好。

POC

CREATE INDEX ON :Person(`pid`);

CALL apoc.export.csv.query("LOAD CSV WITH HEADERS FROM 'file:///calls/calls_28.csv' AS line
WITH toInteger(line.Source) AS Source, 
datetime(replace(line.Time,' ','T')) AS time,
toInteger(line.Target) AS Target,
toInteger(line.Duration) AS Duration
MATCH (p1:Person {pid: Source})
MATCH (p2:Person {pid: Target})
RETURN ID(a) AS ida,ID(b) as idb,time,Duration","rels.csv", {});

然后是

USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM 'file:////rels.csv' AS row
MATCH (a:Person) WHERE ID(a) = toInt(row.ida)
MATCH (b:Person) WHERE ID(b) = toInt(row.idb)
MERGE (b)-[:CALLS {time: row.time, duration: Duration}]->(a);

对我来说,这是最好的方法。