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

时间:2020-06-03 21:59:35

标签: neo4j cypher import-csv

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

我对我的图进行了建模,其中人是节点(person_id为属性),调用为关系(时间和持续时间为属性)。 大约有2,00,000个节点和大约7,000万个关系。我有一个单独的带有个人ID的csv文件,该文件用于创建节点。我还在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分钟。 有人可以将我链接到一种高效且简便的方法吗?

这是密码查询:

: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

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

如果使用每个节点的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);

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

相关问题