一、导入工具
导入CSV文件的方式:
- Load CSV 指令 (增量式导入的导入到原数据库总)
- neo4j-import 、neo4j-admin命令行工具(导入到新建的数据库中)
- 第三方导入工具,如batch-import (不推荐)
batch-import工具下载地址:https://github.com/jexp/batch-import
Neo4j命令行导入工具有两种:
- neo4j-import
- neo4j-admin import (推荐使用)
两种工具使用方式相同,推荐使用neo4j-admin import
1.1、准备csv数据文件
以电影、演员和角色图数据集为例,先将path_to_target_directory修改为数据库文件目录,默认安装下path_to_target_directory指向<neo4j-home>/data/databases/graph.db文件。其中电影节点文件为movies.csv,每部电影都有一个编号id,便于外部数据源的引用,另外每部电影都有电影名和年份属性,并为每个节点添加了Movie和Sequel标签。该文件内容示例如下:
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,每个演员有两个属性:编号(姓名的缩写)、姓名,并带有Actor属性,该文件内容示例如下:
personId:ID,name,:LABEL
keanu,"Keanu Reeves",Actor
laurence,"Laurence Fishburne",Actor
carrieanne,"Carrie-Anne Moss",Actor
接下来,角色文件为roles.csv,保存演员与电影之间的关系,START_ID为演员节点中的编号,END_ID为电影中的编号,role字段为该演员在这部电影中所扮演的角色名,TYPE字段为关系类型(在本例中为ACTED_IN)。该文件内容示例如下:
: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
1.2、使用导入命令导入
导入前确保Neo4j是关闭的状态
注意 :neo4j-import、neo4j-admin import 工具,并不是增量往数据库里导入数据,而已直接生成一个导入了csv数据的新数据库
接下来调用数据导入neo4j-import命令如下:
neo4j-import --into newgraph.db --nodes movies.csv --nodes actors.csv --relationships roles.csv
注意:movies.csv actors.csv roles.csv三个文件必须放在neo4j-import命令文件同一目录下,否则必须指定完整路径 另外,–into newgraph.db 会在neo4j-import命令文件同一目录下创建一个新的 graph.db数据文件,而不是neo4j默认数据库,想要导入到neo4j默认数据库,需要指定默认数据库graph.db的完整路径
neo4j- admin import命令如下:
neo4j-admin import --nodes movies.csv --nodes actors.csv --relationships roles.csv
neo4j- admin 不指定导入的目标数据库则默认为neo4j的默认数据库
完成后则可以启动数据库,命令如下:
neo4j start
1.3、CSV文件注意事项
在创建输入文件时需要注意如下几点:
- 默认情况下,字段以逗号分隔,但可以指定其它分隔符;
- 所有文件必须使用相同的分隔符;
- 节点和关系可以保存在多个数据源;
- 数据源可来源于多个文件;
- 提供数据字段信息的标题必须位于每个数据源的第一行;
- 在标题中没有相应信息的字段将不会被导入;
- 采用UTF-8编码。
导入时不需要创建索引,导入完成后再添加。
如果无法使用此工具进行数据导入,且加载的CSV文件为中小型,可以使用LOAD CSV方式。
1.4、 CSV文件头格式
每个数据源的标题行负责解释文件中的字段,标题行与余下数据行具有相同的定界符。每个字段的格式为:<name>:<field_type>,<name>为属性值, <field_type>用于节点和关系:
属性值(Property value)——数据类型可以是:int、long、float、double、boolean、byte、short、char、string。如果未指定数据类型,则默认为string类型。数组类型在上述类型后面加上[]即可。默认情况下,数组值由分号(;)分隔,也可以使用--array-delimiter指定为其它分隔符。
节点(Node)——节点须有ID和LABEL字段,每个节点在导入前必须指定唯一编号(ID),以利于在创建关系时能正确查找到相应的节点。ID必须唯一,即使某节点具有不同的标签。LABEL字段用于读取一个或多个标签,与数组类似,多个标签由分号(;)分隔,或由--array-delimiter来指定分隔符。
关系(Relationship)——对于关系数据源,有三个必填字段:TYPE、START_ID和END_ID。TYPE为关系类型,START_ID为关系起始节点编号,END_ID为关系终止节点编号。
导入工具默认假定节点标识符在节点之间是唯一的。如果不唯一,还可以定义一个编号空间(ID space),编号空间由节点文件的ID字段来定义。例如,要指定Person 的编号空间,只需在people节点文件中使用字段类型ID(Person),在关系文件(即START_ID(Person)或END_ID(Person))中引用该编号空间即可。
1.5、命令行运行导入工具
在Unix/Linux/OSX操作系统中,导入工具命令名为neo4j-import。与安装配置相关,导入工具可能在任意路径下调用,可能仅在安装目录中执行。而Windows系统则在安装目录下执行bin\neo4j-import命令即可。该命令有如下参数:
--into <store-dir>:要导入到的数据库目录,该目录下不能包含已有数据库。
--nodes[:Label1:Label2] "<file1>,<file2>,…":节点CSV标题和数据,如果带有多个文件将在逻辑上视为一个大文件。第一行必须为标题,每个数据源都有自己的标题。注意,一组文件必须用引号括起来。
--relationships[:RELATIONSHIP_TYPE] "<file1>,<file2>,…":关系CSV标题和数据。同样,多个文件将在逻辑上视为一个大文件,第一行必须为标题,每个数据源都有自己的标题,一组文件必须用引号括起来。
--delimiter <delimiter-character>:CSV文件中数据分隔符或TAB制表符,缺省为逗号。
--array-delimiter <array-delimiter-character>:CSV文件中数组元素之间的分隔符或TAB制表符,缺省为封号。
--quote <quotation-character>:设定CSV数据中值的引用字符,缺省为引号。引号里面的引号需要转义,比如:"""Go away"", he said."和"\"Go away\", he said."两种方式系统都支持。如果设置'为引用字符,则上例需要改写为:'"Go away", he said.'
--multiline-fields <true/false>:来自输入字段是否可以跨行,即是否包含换行符,默认不包含,即值为:false。
--input-encoding <character set>:输入数据的编码字符集,必须是JVM中的可用字符集,可通过Charset#availableCharsets()方法查询获取,如果未指定编码,则使用JVM的缺省字符集。
--ignore-empty-strings <true/false>:空字符串字段是否被忽略,默认不忽略,值为:false。
--id-type <id-type>:指定节点/关系中编号字段的数据类型,可以为:STRING、INTEGER、ACTUAL。STRING:为字符串;INTEGER:为整数值;ACTUAL:以实际节点标识为其类型。默认值为:STRING。
--processors <max processor count>:(高级选项)指定导入工具可以使用的最多处理器数量。默认为JVM所检测的可用处理器数。为了获得最佳性能,此值不应大于可用处理器的数量。
--stacktrace <true/false>:是否启用打印错误堆栈跟踪信息。
--bad-tolerance <max number of bad entries>:容忍导入错误的数据条数,输入数据中的格式错误被视为错误,默认值为1000。
--skip-bad-relationships <true/false>:导入是否跳过缺失节点编号的关系,即关系中未指定开始或结束节点编号,默认跳过,值为true。
--skip-duplicate-nodes <true/false>:是否跳过导入相同编号的节点。默认值:false。
--ignore-extra-columns <true/false>:是否忽略标题中未指定的额外数据列,默认值:false。
--db-config <path/to/neo4j.conf>:(高级选项)指定数据库特定配置的文件路径。与导入工具相关的配置参数有三个,分别为:dbms.relationship_grouping_threshold、unsupported.dbms.block_size.strings、unsupported.dbms.block_size.array_properties。
调用导入工具在某些情况下,可能引发意外错误,可以带上--stacktrace参数打印错误信息,以利于开发和调试。在导入进行过程中,控制台上还将输出相关的统计数据,输出内容可分成几个部分,输出越宽,则导入消耗的时间越多,最宽的部分可认为是瓶颈,用*标记。如果有双行,而不是单行,则表明多线程运行。最右边显示一个数字,指出该阶段处理的实体(节点或关系)数量。例如:
[*>:20,25 MB/s----------|PREPARE(3)=========|RELATIONSHIP(2)=========] 16M
上例中>正在读取解析数据,速度为2025 MB/s;PREPARE为准备数据;RELATIONSHIP为创建实际关系记录;v表示正在写入的要存储的关系,该步骤在这个例子中没有显示,是因为这一步所花时间相对于其它步骤而言要少得多。通过输出的信息可以改善数据库系统的性能,上例中,瓶颈是在数据读取部分(用>标记处),这可能表明:磁盘速度较慢,或系统在导入数据的同时还在进行读写操作。
二、LOAD CSV 导入
LOAD CSV用于从CSV文件中导入数据。
- CSV文件的URL可以由FROM后面紧跟的任意表达式来指定。
- 需要使用AS来为CSV数据指定一个变量
- LOAD CSV支持以gzip,Deflate和ZIP压缩的资源
- CSV文件可以存在数据库服务器上,通过file:///URL来访问。LOAD CSV也支持通过HTTPS、HTTP和FTP来访问CSV文件。
- LOAD CSV支持HTTP重定向,但基于安全考虑,重定向时不能改变协议类型,比如从HTTPS重定向到HTTP。
文件URL的配置项
dbms.security.allow_csv_import_from_file_urls[1]
这个选项决定Cypher在使用LOAD CSV时是否支持使用fille:/// URL来加载数据。该URL唯一标识了数据库服务器文件系统上的文件。dbms.security.allow_csv_import_from_file_urls=false将完全禁止LOAD CSV访问文件系统。
dbms.directories.import[2]
设置LOAD CSV中file:/// URL中的根路径。这必须设置为数据库服务器上的文件系统的单个目录,它让所有的请求从file:/// URL加载时都使用根路径的相对路径(类似unix下的chroot操作)。默认值是import,这是基于安全考虑阻止数据库访问标准的import之外的目录下的文件。将dbms.directories.import设置为空将移除这个安全考虑,允许访问系统上的任何文件,但是不推荐这么做。
文件URLs将相对于dbms.directories.import来解析。例如,一个典型的URL类似file:///myfile.csv或者file:///myproject/myfile.csv。
- 如果dbms.directories.import设置的是默认值import,那么在LOAD CSV语句将分别从<NEO4J_HOME>/import/myfile.csv和<NEO4J_HOME>/import/myproject/myfile.csv中读取数据。
- 如果设置为/data/csv,上面的LOAD CSV中的URL将分别从/data/csv/myfile.csv和/data/csv/myproject/myfile.csv中读取数据。
从本地文件导入
LOAD CSV FROM ' file:///artists.csv' AS line
CREATE (:Artist { name: line[1], year: toInt(line[2])})
从HTTP导入
LOAD CSV FROM ' http://neo4j.com/docs/developer-manual/3.1/csv/artists.csv' AS line
CREATE (:Artist { name: line[1], year: toInt(line[2])})
CSV文件格式
使用LOAD CSV导入的CSV文件必须满足如下要求:
- 字符编码为UTF-8;
- 行结束符与操作系统关联,如unix上为\n,windows上为\r\n;
- 默认的字段终止符为,;
- 字段终止符可以使用LOAD CSV中 的FIELDTERMINATOR选项来修改。
- CSV文件允许引号字符串,但读取数据的时候引号字符会被丢弃。
- 字符串的引号字符为双引号"。
- 转义字符为\。
从CSV文件导入数据
从CSV文件导入数据到Neo4j,可以用LOAD CSV把数据加载到查询语句中。然后使用正常的Cypher更新语句将数据写入到数据库中。
artists.csv
"1","ABBA","1992"
"2","Roxette","1986"
"3","Europe","1979"
"4","The Cardigans","1992"
LOAD CSV FROM ' http://neo4j.com/docs/developer-manual/3.1/csv/artists.csv' AS line CREATE (:Artist { name: line[1], year: toInt(line[2])}) |
CSV文件中的每一行都创建一个标签为Artist的节点。CSV文件中的另外两列分别设置为节点的属性。
同时创建节点和关系
LOAD CSV FROM ' http://neo4j.com/docs/developer-manual/3.1/csv/artists.csv' AS line
CREATE (n:Artist { name: line[1], year: toInt(line[2])}), (n:Artist { name: line[1], year: toInt(line[2])})
CREATE (n)-[r: line[1]]->(m)
导入包含文件头的CSV文件
当导入的CSV文件包含文件头时,可以把每一行看作一个map,而不是字符串数组。
artists.csv
"Id","Name","Year"
"1","ABBA","1992"
"2","Roxette","1986"
"3","Europe","1979"
"4","The Cardigans","1992"
LOAD CSV WITH HEADERS FROM 'http://neo4j.com/docs/developer-manual/3.1/csv/artists-with-headers.csv' AS line CREATE (:Artist { name: line.Name, year: toInt(line.Year)}) |
这时,文件的开始行包含列的名称。指定WITH HEADERS后,可以通过对应的列名来访问指定的字段。
导入自定义分隔符的CSV文件
CSV文件的分隔符有时候不是逗号,而是其他分隔符。这时,可以使用FIELDTERMINATOR来指定。
artists-fieldterminator.csv
"1";"ABBA";"1992"
"2";"Roxette";"1986"
"3";"Europe";"1979"
"4";"The Cardigans";"1992"
LOAD CSV FROM 'http://neo4j.com/docs/developer-manual/3.1/csv/artists-fieldterminator.csv' AS line FIELDTERMINATOR ';' CREATE (:Artist { name: line[1], year: toInt(line[2])}) |
本例中字段之间以分号分隔,因此,在LOAD CSV中使用了FIELDTERMINATOR自定义分隔符。
导入巨量数据
如果导入的CSV文件包含百万数量级的行,可以使用USING PERIODIC COMMIT来指导Neo4j每导入一定数量行之后就提交(commit)一次。这样可避免在事务过程中耗费大量的内存。默认情况下,每1000行会提交一次。
USING PERIODIC COMMIT LOAD CSV FROM 'http://neo4j.com/docs/developer-manual/3.1/csv/artists.csv' AS line CREATE (:Artist { name: line[1], year: toInt(line[2])}) |
设置提交频率
可以设置提交的频率,如本例中设置为500行。
USING PERIODIC COMMIT 500 LOAD CSV FROM 'http://neo4j.com/docs/developer-manual/3.1/csv/artists.csv' AS line CREATE (:Artist { name: line[1], year: toInt(line[2])}) |
导入包含转义字符的数据
本例中同时包含了引用字符和转义字符。
artists-with-escaped-char.csv
"1","The ""Symbol""","1992"
LOAD CSV FROM 'http://neo4j.com/docs/developer-manual/3.1/csv/artists-with-escaped-char.csv' AS line CREATE (a:Artist { name: line[1], year: toInt(line[2])}) RETURN a.name AS name, a.year AS year, length(a.name) AS length |
注意:这里的字符串用双引号括起来。同时,关注本例中字符串的长度
三、导出
导出文件的方式:
- 使用web控制台上的 导出csv 功能
- 使用neo4j-apoc-procedures导出csv 文件
- 使用neo4j-apoc-procedures导出Cypher 创建语句
3.1、neo4j-apoc-procedures 安装
neo4j-apoc-procedures文档:https://neo4j-contrib.github.io/neo4j-apoc-procedures/
使用neo4j-apoc-procedures步骤:
1、下载与Neo4j相应版本的jar包:https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases
2、把jar包放在安装目录的plugins文件夹下
3、在配置文件neo4j.conf里添加
apoc.export.file.enabled=true
apoc.import.file.enabled=true
dbms.security.procedures.unrestricted=apoc.*
4、重启Neo4j服务
5、在可视化界面运行:return apoc.version(),如果出现对应的版本号,证明安装成功
3.2、使用neo4j-apoc-procedures导出csv 文件
导出csv文件
call apoc.export.csv.query("MATCH (n)-[r]-(m) return n,r,m","d:/movie.csv",{format:'plain',cypherFormat:'updateStructure'})
3.3、使用neo4j-apoc-procedures导出Cypher 创建语句
导出Cypher 语句
call apoc.export.cypher.query("MATCH (n)-[r]-(m) return n,r,m","d:/movie.cypher")