1

我正在为 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 万个节点(保存为 call_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

4

2 回答 2

0

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

您应该考虑使用它是否安全,CREATE而不是MERGE.

于 2020-06-03T22:43:06.170 回答
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);

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

于 2020-06-05T19:21:07.560 回答