知识库

将(子)图导出为 Cypher 脚本并再次导入

通常情况下,你会想将完整(或部分)数据库导出到文件并再次导入,而不复制实际的数据库文件。如果你想后者,请使用 neo4j-admin dump/load

下面有两种方法可以从你的数据库或 Cypher 语句创建 Cypher 脚本文件。这也可以用于降级(更小的)数据库。

格式

以下是这些工具生成的格式说明

  • 重新创建索引和约束

  • 每个节点的简单语句(CREATE)/每个关系的语句(2 次 MATCH + CREATE

  • 可选地,你可以将导出配置为使用 MERGE 而不是 CREATE

  • 批量创建数据(默认 40k),可选地用 :begin:commit 包裹

  • 使用现有约束进行节点查找

  • 如果该标签不存在约束,则使用人工约束 + 属性(UNIQUE IMPORT LABEL.UNIQUE IMPORT ID),其中属性值为节点 ID,在节点创建时使用

  • 在结束时批量清理人工标签、属性和约束

APOC

你可以安装 APOC 过程库。

然后使用 apoc.export.cypher.* 过程从你的图或数据创建 export.cypher 文件。更多信息请参阅 文档,下面给出一些示例。

这些过程提供配置选项,可生成不同输出格式,并且可以将节点、关系和模式脚本分割到不同的文件中。

请注意,必须先在 neo4j.conf 中启用写入和读取文件的功能。
apoc.export.file.enabled=true
apoc.import.file.enabled=true
// exports the whole database incl. indexes as cypher statements to the provided file
CALL apoc.export.cypher.all('/tmp/export.cypher',{format:'cypher-shell'})

// exports given nodes and relationships incl. indexes as cypher statements to the provided file
MATCH path = (p1:Person)-[r:KNOWS]->(p2:Person)
WITH collect(p1)+collect(p2) as export_nodes, collect(r) as export_rels
CALL apoc.export.cypher.data(export_nodes,export_rels,'/tmp/export.cypher',{format:'cypher-shell'})
YIELD file, source, format, nodes, relationships, properties, time
RETURN nodes, relationships, time;

// exports given graph object incl. indexes as cypher statements to the provided file
...
CALL apoc.graph.fromPaths([paths],'export_graph',{}) YIELD graph
CALL apoc.export.cypher.graph(graph,'/tmp/export.cypher',{format:'cypher-shell'}) YIELD time
RETURN time;

// exports nodes and relationships from the cypher statement incl. indexes as cypher statements to the provided file
CALL apoc.export.cypher.query(
'MATCH (p1:Person)-[r:KNOWS]->(p2:Person) RETURN *',
'/tmp/export.cypher',{format:'cypher-shell'});

使用 cypher-shell 进行导入

如果你使用 cypher-shell 格式导出文件,其包含在 shell 中进行事务的正确语法。

然后你也可以使用 cypher-shell 导入它们。

$ cat /tmp/export.cypher | ./bin/cypher-shell -u neo4j -p password

导出文件示例

// create nodes
:begin
CREATE (:`UNIQUE IMPORT LABEL` {`UNIQUE IMPORT ID`:0});
CREATE (:`User` {`age`:43, `name`:"User1"});
:commit

// add schema
:begin
CREATE INDEX ON :`User`(`age`);
CREATE CONSTRAINT ON (node:`User`) ASSERT node.`name` IS UNIQUE;
CREATE CONSTRAINT ON (node:`UNIQUE IMPORT LABEL`) ASSERT node.`UNIQUE IMPORT ID` IS UNIQUE;
:commit

// wait for index completion
call db.awaitIndexes();

// create relationships
:begin
MATCH (n1:`UNIQUE IMPORT LABEL`{`UNIQUE IMPORT ID`:0}), (n2:`User`{`name`:"User1"}) CREATE (n1)-[:`KNOWS` {`since`:2011}]->(n2);
:commit

// clean up temporary import keys (batched)
:begin
MATCH (n:`UNIQUE IMPORT LABEL`)  WITH n LIMIT 1000 REMOVE n:`UNIQUE IMPORT LABEL` REMOVE n.`UNIQUE IMPORT ID`;
:commit
:begin
DROP CONSTRAINT ON (node:`UNIQUE IMPORT LABEL`) ASSERT node.`UNIQUE IMPORT ID` IS UNIQUE;
:commit
© . This site is unofficial and not affiliated with Neo4j, Inc.