Neo4j-admin 导入

本教程提供详细的示例,以说明使用命令 neo4j-admin database import 从 CSV 文件导入数据的功能。导入命令用于从 CSV 文件加载大量数据,并支持将数据完整或增量导入到正在运行或已停止的 Neo4j DBMS 中。

neo4j-admin database import 命令不会创建数据库,该命令只导入数据并使其可供数据库使用。在执行 neo4j-admin database import 命令之前,数据库必须不存在,并且应该在执行完命令后创建。如果数据库已存在,则该命令将退出并显示错误消息。

关系是通过连接节点 ID 创建的,每个节点都应具有唯一的 ID,以便在创建节点之间的关系时能够引用它。在以下示例中,节点 ID 存储为节点上的属性。如果您不想在导入完成后将 ID 保留为属性,则不要在 :ID 字段中指定属性名称。

这些示例展示了如何在独立的 Neo4j DBMS 中导入数据。它们使用

  • Neo4j 压缩包(Unix 控制台应用程序)。

  • $NEO4J_HOME 作为当前工作目录。

  • 默认数据库 neo4j

  • Neo4j 安装的 import 目录用于存储所有 CSV 文件。但是,CSV 文件可以位于文件系统中的任何目录。

  • UNIX 样式路径。

  • neo4j-admin database import 命令。

实用提示
  • 可以在 CSV 标题格式 中找到 CSV 文件标题格式的详细信息。

  • 要显示可用数据库,请对 system 数据库使用 Cypher 查询 SHOW DATABASES

  • 要删除数据库,请对 system 数据库使用 Cypher 查询 DROP DATABASE database_name

  • 要创建数据库,请对 system 数据库使用 Cypher 查询 CREATE DATABASE database_name

导入小型数据集

在本例中,您将导入一个包含节点和关系的小型数据集。数据集被分成三个 CSV 文件,每个文件都有一个描述数据的标题行。

数据

数据集包含有关电影、演员和角色的信息。电影和演员的数据作为节点存储,角色作为关系存储。

您要从中导入数据的文件是

  • movies.csv

  • actors.csv

  • roles.csv

movies.csv 中的每部电影都有一个 ID、一个 title 和一个 year,它们存储为节点中的**属性**。movies.csv 中的所有节点也都具有**标签** Movie。一个节点可以有多个标签,正如您在 movies.csv 中看到的,有些节点也具有标签 Sequel。节点标签是可选的,它们对于将节点分组到集合中非常有用,其中所有具有特定标签的节点都属于同一个集合。

movies.csv
movieId:ID,title,year:int,:LABEL
tt0133093,"The Matrix",1999,Movie
tt0234215,"The Matrix Reloaded",2003,Movie;Sequel
tt0242653,"The Matrix Revolutions",2003,Movie;Sequel

actors.csv 中的演员数据包含一个 ID 和一个 name,它们存储为节点中的**属性**。在这种情况下,ID 是演员姓名的一种简写。actors.csv 中的所有节点都具有标签 Actor

actors.csv
personId:ID,name,:LABEL
keanu,"Keanu Reeves",Actor
laurence,"Laurence Fishburne",Actor
carrieanne,"Carrie-Anne Moss",Actor

roles.csv 中的角色数据只有一个**属性** role。角色由连接演员节点和电影节点的关系数据表示。

关系数据有三个必填字段

  1. :START_ID — 引用节点的 ID。

  2. :END_ID — 引用节点的 ID。

  3. :TYPE — 关系类型。

要创建两个节点之间的关系,actors.csvmovies.csv 中定义的 ID 用于 :START_ID:END_ID 字段。您还需要为 :TYPE 字段提供一个关系类型(在本例中为 ACTED_IN)。

roles.csv
:START_ID,role,:END_ID,:TYPE
keanu,"Neo",tt0133093,ACTED_IN
keanu,"Neo",tt0234215,ACTED_IN
keanu,"Neo",tt0242653,ACTED_IN
laurence,"Morpheus",tt0133093,ACTED_IN
laurence,"Morpheus",tt0234215,ACTED_IN
laurence,"Morpheus",tt0242653,ACTED_IN
carrieanne,"Trinity",tt0133093,ACTED_IN
carrieanne,"Trinity",tt0234215,ACTED_IN
carrieanne,"Trinity",tt0242653,ACTED_IN

导入数据

  • 节点数据的路径用 --nodes 选项定义。

  • 关系数据的路径用 --relationships 选项定义。

neo4j-admin database import 的调用将如下所示

shell
bin/neo4j-admin database import full neo4j --nodes=import/movies.csv --nodes=import/actors.csv --relationships=import/roles.csv

查询数据

要查询数据。启动 Neo4j。

默认用户名和密码是 neo4jneo4j

shell
bin/neo4j start

要查询图形中的导入数据,请尝试一个简单的 Cypher 查询。

shell
bin/cypher-shell --database=neo4j "MATCH (n) RETURN count(n) as nodes"

停止 Neo4j。

shell
bin/neo4j stop

CSV 文件分隔符

如果您要导入的数据不符合默认格式,则可以自定义导入工具使用的配置选项(请参阅 选项)。

可以在 CSV 标题格式 中找到 CSV 文件标题格式的详细信息。

数据

以下 CSV 文件具有

  • --delimiter=";"

  • --array-delimiter="U+007C" (U+007C 是字符 | 的 Unicode 代码点)

  • --quote="'"

movies2.csv
movieId:ID;title;year:int;:LABEL
tt0133093;'The Matrix';1999;Movie
tt0234215;'The Matrix Reloaded';2003;Movie|Sequel
tt0242653;'The Matrix Revolutions';2003;Movie|Sequel
actors2.csv
personId:ID;name;:LABEL
keanu;'Keanu Reeves';Actor
laurence;'Laurence Fishburne';Actor
carrieanne;'Carrie-Anne Moss';Actor
roles2.csv
:START_ID;role;:END_ID;:TYPE
keanu;'Neo';tt0133093;ACTED_IN
keanu;'Neo';tt0234215;ACTED_IN
keanu;'Neo';tt0242653;ACTED_IN
laurence;'Morpheus';tt0133093;ACTED_IN
laurence;'Morpheus';tt0234215;ACTED_IN
laurence;'Morpheus';tt0242653;ACTED_IN
carrieanne;'Trinity';tt0133093;ACTED_IN
carrieanne;'Trinity';tt0234215;ACTED_IN
carrieanne;'Trinity';tt0242653;ACTED_IN

导入数据

neo4j-admin database import 的调用将如下所示

shell
bin/neo4j-admin database import full neo4j --delimiter=";" --array-delimiter="U+007C" --quote="'" --nodes=import/movies2.csv --nodes=import/actors2.csv --relationships=import/roles2.csv

使用单独的标题文件

在处理非常大的 CSV 文件时,将标题放在单独的文件中会更加方便。这样可以更轻松地编辑标题,因为您无需打开一个巨大的数据文件才能更改它。标题文件必须在每个文件组中其他文件的前面指定。

导入工具还可以处理单文件压缩存档,例如

  • --nodes=import/nodes.csv.gz

  • --relationships=import/relationships.zip

数据

您将使用与前一个示例中相同的 数据集,但标题在单独的文件中。

movies3-header.csv
movieId:ID,title,year:int,:LABEL
movies3.csv
tt0133093,"The Matrix",1999,Movie
tt0234215,"The Matrix Reloaded",2003,Movie;Sequel
tt0242653,"The Matrix Revolutions",2003,Movie;Sequel
actors3-header.csv
personId:ID,name,:LABEL
actors3.csv
keanu,"Keanu Reeves",Actor
laurence,"Laurence Fishburne",Actor
carrieanne,"Carrie-Anne Moss",Actor
roles3-header.csv
:START_ID,role,:END_ID,:TYPE
roles3.csv
keanu,"Neo",tt0133093,ACTED_IN
keanu,"Neo",tt0234215,ACTED_IN
keanu,"Neo",tt0242653,ACTED_IN
laurence,"Morpheus",tt0133093,ACTED_IN
laurence,"Morpheus",tt0234215,ACTED_IN
laurence,"Morpheus",tt0242653,ACTED_IN
carrieanne,"Trinity",tt0133093,ACTED_IN
carrieanne,"Trinity",tt0234215,ACTED_IN
carrieanne,"Trinity",tt0242653,ACTED_IN

导入数据

neo4j-admin database import 的调用将如下所示

文件组的标题行,无论是文件组中的第一行还是专用的标题文件,都必须是文件组中的第一行。

shell
bin/neo4j-admin database import full neo4j --nodes=import/movies3-header.csv,import/movies3.csv --nodes=import/actors3-header.csv,import/actors3.csv --relationships=import/roles3-header.csv,import/roles3.csv

多个输入文件

除了使用单独的标题文件外,您还可以提供多个节点或关系文件。此类输入组中的文件可以使用以 , 分隔的多个匹配字符串来指定,其中每个匹配字符串可以是确切的文件名或匹配一个或多个文件的正则表达式。多个匹配的文件将根据它们的字符及其包含数字的文件名的自然数排序顺序进行排序。

数据

movies4-header.csv
movieId:ID,title,year:int,:LABEL
movies4-part1.csv
tt0133093,"The Matrix",1999,Movie
tt0234215,"The Matrix Reloaded",2003,Movie;Sequel
movies4-part2.csv
tt0242653,"The Matrix Revolutions",2003,Movie;Sequel
actors4-header.csv
personId:ID,name,:LABEL
actors4-part1.csv
keanu,"Keanu Reeves",Actor
laurence,"Laurence Fishburne",Actor
actors4-part2.csv
carrieanne,"Carrie-Anne Moss",Actor
roles4-header.csv
:START_ID,role,:END_ID,:TYPE
roles4-part1.csv
keanu,"Neo",tt0133093,ACTED_IN
keanu,"Neo",tt0234215,ACTED_IN
keanu,"Neo",tt0242653,ACTED_IN
laurence,"Morpheus",tt0133093,ACTED_IN
laurence,"Morpheus",tt0234215,ACTED_IN
roles4-part2.csv
laurence,"Morpheus",tt0242653,ACTED_IN
carrieanne,"Trinity",tt0133093,ACTED_IN
carrieanne,"Trinity",tt0234215,ACTED_IN
carrieanne,"Trinity",tt0242653,ACTED_IN

导入数据

neo4j-admin database import 的调用将如下所示

shell
bin/neo4j-admin database import full neo4j --nodes=import/movies4-header.csv,import/movies4-part1.csv,import/movies4-part2.csv --nodes=import/actors4-header.csv,import/actors4-part1.csv,import/actors4-part2.csv --relationships=import/roles4-header.csv,import/roles4-part1.csv,import/roles4-part2.csv

正则表达式

当有许多数据源文件时,可以使用正则表达式指定文件名。匹配正则表达式的每个文件名都将被包含在内。

如果使用单独的标题文件,为了使导入正常工作,标题文件必须是文件组中的第一个。当使用正则表达式指定输入文件时,文件列表将根据匹配表达式的文件的名称进行排序。匹配会识别文件名中的数字,并相应地对它们进行排序,无需使用零进行填充。

示例 1. 匹配顺序

例如,假设您有以下文件

  • movies4-header.csv

  • movies4-data1.csv

  • movies4-data2.csv

  • movies4-data12.csv

如果您使用正则表达式 movies4.*,排序将把标题文件放在最后,导入将失败。更好的选择是显式命名标题文件并使用仅匹配数据文件名 的正则表达式。例如:--nodes "import/movies4-header.csv,movies-data.*" 将实现此目的。

使用正则表达式导入数据时,对 neo4j-admin database import 的调用可以简化为

shell
bin/neo4j-admin database import full neo4j --nodes="import/movies4-header.csv,import/movies4-part.*" --nodes="import/actors4-header.csv,import/actors4-part.*" --relationships="import/roles4-header.csv,import/roles4-part.*"

不要将正则表达式的使用与 文件通配 混淆。

表达式 .* 表示:“除换行符之外的任何字符的零次或多次出现”。因此,正则表达式 movies4.* 将列出以 movies4 开头的所有文件。相反,使用文件通配时,ls movies4.* 将列出以 movies4. 开头的所有文件。

另一个需要注意的重要区别是排序顺序。正则表达式匹配的结果将把文件 movies4-part2.csv 放在文件 movies4-part12.csv 之前。如果在包含上述文件的目录中执行 ls movies4-part*,文件 movies4-part12.csv 将在文件 movies4-part2.csv 之前列出。

为每个节点使用相同的标签

如果您想为节点文件中的每个节点使用相同的节点标签,可以通过将适当的值指定为 neo4j-admin database import 的选项来实现。这样,您就不必在标题文件中指定 :LABEL 列,并且每行(节点)都将应用从命令行选项指定的标签。

示例 2. 指定节点标签选项

--nodes=LabelOne:LabelTwo=import/example-header.csv,import/example-data1.csv

可以将文件中提供的标签和命令行中提供的标签都应用于节点。

数据

在本例中,您希望在 movies5a.csv 中指定的每个节点上都有标签 Movie,并且在 sequels5a.csv 中指定的节点上具有标签 MovieSequel

movies5a.csv
movieId:ID,title,year:int
tt0133093,"The Matrix",1999
sequels5a.csv
movieId:ID,title,year:int
tt0234215,"The Matrix Reloaded",2003
tt0242653,"The Matrix Revolutions",2003
actors5a.csv
personId:ID,name
keanu,"Keanu Reeves"
laurence,"Laurence Fishburne"
carrieanne,"Carrie-Anne Moss"
roles5a.csv
:START_ID,role,:END_ID,:TYPE
keanu,"Neo",tt0133093,ACTED_IN
keanu,"Neo",tt0234215,ACTED_IN
keanu,"Neo",tt0242653,ACTED_IN
laurence,"Morpheus",tt0133093,ACTED_IN
laurence,"Morpheus",tt0234215,ACTED_IN
laurence,"Morpheus",tt0242653,ACTED_IN
carrieanne,"Trinity",tt0133093,ACTED_IN
carrieanne,"Trinity",tt0234215,ACTED_IN
carrieanne,"Trinity",tt0242653,ACTED_IN

导入数据

neo4j-admin database import 的调用将如下所示

shell
bin/neo4j-admin database import full neo4j --nodes=Movie=import/movies5a.csv --nodes=Movie:Sequel=import/sequels5a.csv --nodes=Actor=import/actors5a.csv --relationships=import/roles5a.csv

为每个关系使用相同的关系类型

如果您想为关系文件中的每个关系使用相同的关系类型,可以通过将适当的值指定为 neo4j-admin database import 的选项来实现。

示例 3. 指定关系类型选项

--relationships=TYPE=import/example-header.csv,import/example-data1.csv

如果您在命令行和关系文件中都提供关系类型,则将应用文件中的关系类型。

数据

在本例中,您希望关系类型 ACTED_IN 应用于 roles5b.csv 中指定的每个关系。

movies5b.csv
movieId:ID,title,year:int,:LABEL
tt0133093,"The Matrix",1999,Movie
tt0234215,"The Matrix Reloaded",2003,Movie;Sequel
tt0242653,"The Matrix Revolutions",2003,Movie;Sequel
actors5b.csv
personId:ID,name,:LABEL
keanu,"Keanu Reeves",Actor
laurence,"Laurence Fishburne",Actor
carrieanne,"Carrie-Anne Moss",Actor
roles5b.csv
:START_ID,role,:END_ID
keanu,"Neo",tt0133093
keanu,"Neo",tt0234215
keanu,"Neo",tt0242653
laurence,"Morpheus",tt0133093
laurence,"Morpheus",tt0234215
laurence,"Morpheus",tt0242653
carrieanne,"Trinity",tt0133093
carrieanne,"Trinity",tt0234215
carrieanne,"Trinity",tt0242653

导入数据

neo4j-admin database import 的调用将如下所示

shell
bin/neo4j-admin database import full neo4j --nodes=import/movies5b.csv --nodes=import/actors5b.csv --relationships=ACTED_IN=import/roles5b.csv

属性

节点和关系可以具有属性。属性类型在 CSV 标题行中指定,请参阅 CSV 标题格式

数据

以下示例创建一个小型图形,其中包含一个演员和一部电影,它们通过一个关系连接。

关系上有一个 roles 属性,该属性包含演员在电影中扮演的角色数组

movies6.csv
movieId:ID,title,year:int,:LABEL
tt0099892,"Joe Versus the Volcano",1990,Movie
actors6.csv
personId:ID,name,:LABEL
meg,"Meg Ryan",Actor
roles6.csv
:START_ID,roles:string[],:END_ID,:TYPE
meg,"DeDe;Angelica Graynamore;Patricia Graynamore",tt0099892,ACTED_IN

导入数据

neo4j-admin database import 的调用将如下所示

shell
bin/neo4j-admin database import full neo4j --nodes=import/movies6.csv --nodes=import/actors6.csv --relationships=import/roles6.csv

ID 空间

导入工具假设标识符在所有节点文件中都是唯一的。对于使用顺序、自动递增或其他方式冲突的标识符的数据集,情况可能并非如此。这些数据集可以定义 ID 空间,其中标识符在其各自的 ID 空间内是唯一的。

在节点 ID 仅在文件中唯一的情况下,使用 ID 空间是确保所有节点文件之间唯一性的方法。请参阅 使用 ID 空间

neo4j-admin database import 处理的每个节点都必须提供一个 ID,如果要将其连接到任何关系中。节点 ID 用于在创建关系时查找起始节点和结束节点。

从 Neo4j 5.3 开始,节点标题还可以包含多个 ID 列,其中关系数据引用所有这些列的复合值。这也意味着使用 string 作为 id-type。对于每个 ID 列,您可以指定将它的值存储为不同的节点属性。但是,复合值不能存储为节点属性。

示例 4. ID 空间

要为 movieId:ID 定义 ID 空间 Movie-ID,请使用语法 movieId:ID(Movie-ID)

数据

例如,如果电影和人物都使用顺序标识符,那么您将定义 MovieActor ID 空间。

movies7.csv
movieId:ID(Movie-ID),title,year:int,:LABEL
1,"The Matrix",1999,Movie
2,"The Matrix Reloaded",2003,Movie;Sequel
3,"The Matrix Revolutions",2003,Movie;Sequel
actors7.csv
personId:ID(Actor-ID),name,:LABEL
1,"Keanu Reeves",Actor
2,"Laurence Fishburne",Actor
3,"Carrie-Anne Moss",Actor

您还需要在关系文件中引用适当的 ID 空间,以便它知道要连接哪些节点。

roles7.csv
:START_ID(Actor-ID),role,:END_ID(Movie-ID)
1,"Neo",1
1,"Neo",2
1,"Neo",3
2,"Morpheus",1
2,"Morpheus",2
2,"Morpheus",3
3,"Trinity",1
3,"Trinity",2
3,"Trinity",3

导入数据

neo4j-admin database import 的调用将如下所示

shell
bin/neo4j-admin database import full neo4j --nodes=import/movies7.csv --nodes=import/actors7.csv --relationships=ACTED_IN=import/roles7.csv

跳过引用缺失节点的关系

导入工具对错误实体(关系或节点)零容忍,并在遇到第一个错误实体时停止导入。您可以明确指定忽略包含错误实体的行。

有两种类型的错误输入

  1. 错误关系。

  2. 错误节点。

引用缺失节点 ID 的关系(无论是 `:START_ID` 还是 `:END_ID`)都被视为错误关系。是否跳过此类关系由 `--skip-bad-relationships` 标志控制,该标志可以取值为 `true` 或 `false`,或者不指定值,表示 `true`。默认值为 `false`,这意味着任何错误关系都被视为错误,并会导致导入失败。有关更多信息,请参见 `--skip-bad-relationships` 选项。

数据

在以下示例中,roles 文件中引用了缺失的 `emil` 节点。

movies8a.csv
movieId:ID,title,year:int,:LABEL
tt0133093,"The Matrix",1999,Movie
tt0234215,"The Matrix Reloaded",2003,Movie;Sequel
tt0242653,"The Matrix Revolutions",2003,Movie;Sequel
actors8a.csv
personId:ID,name,:LABEL
keanu,"Keanu Reeves",Actor
laurence,"Laurence Fishburne",Actor
carrieanne,"Carrie-Anne Moss",Actor
roles8a.csv
:START_ID,role,:END_ID,:TYPE
keanu,"Neo",tt0133093,ACTED_IN
keanu,"Neo",tt0234215,ACTED_IN
keanu,"Neo",tt0242653,ACTED_IN
laurence,"Morpheus",tt0133093,ACTED_IN
laurence,"Morpheus",tt0234215,ACTED_IN
laurence,"Morpheus",tt0242653,ACTED_IN
carrieanne,"Trinity",tt0133093,ACTED_IN
carrieanne,"Trinity",tt0234215,ACTED_IN
carrieanne,"Trinity",tt0242653,ACTED_IN
emil,"Emil",tt0133093,ACTED_IN

导入数据

neo4j-admin database import 的调用将如下所示

shell
bin/neo4j-admin database import full neo4j --nodes=import/movies8a.csv --nodes=import/actors8a.csv --relationships=import/roles8a.csv

由于输入数据中存在错误关系,因此导入过程将失败。

让我们看看附加 `--skip-bad-relationships` 标志后会发生什么

shell
bin/neo4j-admin database import full neo4j --skip-bad-relationships --nodes=import/movies8a.csv --nodes=import/actors8a.csv --relationships=import/roles8a.csv

数据文件已成功导入,错误关系被忽略。一个条目写入 `import.report` 文件。

忽略错误关系
InputRelationship:
   source: roles8a.csv:11
   properties: [role, Emil]
   startNode: emil (global id space)
   endNode: tt0133093 (global id space)
   type: ACTED_IN
 referring to missing node emil

跳过具有相同 ID 的节点

在 ID 空间中已指定 `:ID` 的节点被视为错误节点。是否跳过此类节点由 `--skip-duplicate-nodes` 标志控制,该标志可以取值为 `true` 或 `false`,或者不指定值,表示 `true`。默认值为 `false`,这意味着任何重复节点都被视为错误,并会导致导入失败。有关更多信息,请参见 `--skip-duplicate-nodes` 选项。

数据

在以下示例中,节点 ID `laurence` 在同一个 ID 空间中被指定了两次。

actors8b.csv
personId:ID,name,:LABEL
keanu,"Keanu Reeves",Actor
laurence,"Laurence Fishburne",Actor
carrieanne,"Carrie-Anne Moss",Actor
laurence,"Laurence Harvey",Actor

导入数据

neo4j-admin database import 的调用将如下所示

shell
bin/neo4j-admin database import full neo4j --database=neo4j --nodes=import/actors8b.csv

由于输入数据中存在错误节点,因此导入过程将失败。

让我们看看附加 `--skip-duplicate-nodes` 标志后会发生什么

shell
bin/neo4j-admin database import full neo4j --skip-duplicate-nodes --nodes=import/actors8b.csv

数据文件已成功导入,错误节点被忽略。一个条目写入 `import.report` 文件。

忽略错误节点
ID 'laurence' is defined more than once in global ID space, at least at actors8b.csv:3 and actors8b.csv:5