前言
大家好,我是半虹
这篇文章主要讲解如何批量导入 CSV 数据到 Neo4j 数据库
正文
0、CSV 数据
为了更方便地添加数据,Neo4j 有提供批量导入 CSV 数据的功能
在介绍如何导入数据前,我们有必要先了解一下,Neo4j 对 CSV 数据的格式要求
CSV 文件的首行一般是表头,用于指定其包含的字段,字段间用 , 分隔,每个字段的格式为 名称:类型
名称和类型至少有一个,常见的类型有 int、float、string,如果类型省略,则默认是 string
ID、LABEL 和 TYPE 也是类型,分别表示标识、节点标签和关系类型,当使用这些类型时,名称可以忽略
CSV 文件可能有很多个,大体可以分成两类,一类是节点文件,一类是关系文件
在关系文件中,还有两种特殊类型 START_ID 和 END_ID 分别用于指定关系的头节点和尾节点
在节点文件中,如果可能有相同的 ID,则必须指定命名空间,格式为 ID(命名空间名称)
另外,CSV 文件推荐使用无 BOM 的 UTF-8 编码,可解决中文乱码的问题
1、命令导入
命令导入适用于中小型数据
可以使用 neo4j-shell
或 cypher-shell
打开终端,然后使用 LOAD CSV
命令导入数据
但是现在 neo4j-shell
已经过时,推荐使用 cypher-shell
导入的文件需要放在 import
目录下
如果希望从本地其它位置导入或者从远程导入,需要修改 conf/neo4j.conf
配置文件
# LOAD CSV 使用的文件路径,如果将其注释,则可以从任何位置导入文件 dbms.directories.import=import # 是否允许从远程 LOAD CSV,如果打开注释,则表示允许从远程导入文件 #dbms.security.allow_csv_import_from_file_urls=true
如果 CSV 文件首行是表头,则需要带有 WITH HEADERS 参数,并且用名称获取属性,否则用下标获取属性
另外 CSV 默认以 string 类型读取数据,可通过 toInteger()、toFloat() 函数转换成需要的类型
最后 FROM 用于指定导入的文件,AS 可以给导入的文件命名,FIELDTERMINATOR 指定导入文件的分割符
数据示例:
poet.csv
(节点文件)
id,name t0,李白 t1,杜甫 t2,白居易 t3,王维 t4,李商隐 t5,苏轼 t6,辛弃疾 t7,李清照 t8,柳永 t9,陆游
poem.csv
(节点文件)
id,name m0,将进酒 m1,茅屋为秋风所破歌 m2,琵琶行 m3,使至塞上 m4,锦瑟 m5,定风波·莫听穿林打叶声 m6,永遇乐·京口北固亭怀古 m7,一剪梅·红藕香残玉簟秋 m8,雨霖铃·寒蝉凄切 m9,诉衷情·当年万里觅封侯
edge.csv
(关系文件)
source,target,relation t0,m0,作品 t1,m1,作品 t2,m2,作品 t3,m3,作品 t4,m4,作品 t5,m5,作品 t6,m6,作品 t7,m7,作品 t8,m8,作品 t9,m9,作品
命令示例:
LOAD CSV WITH HEADERS FROM 'file:///poet.csv' AS line FIELDTERMINATOR ',' MERGE (:poet{id:line.id,name:line.name});
LOAD CSV WITH HEADERS FROM 'file:///poem.csv' AS line FIELDTERMINATOR ',' MERGE (:poem{id:line.id,name:line.name});
LOAD CSV WITH HEADERS FROM 'file:///edge.csv' AS line FIELDTERMINATOR ',' MATCH (s:poet{id:line.source}),(t:poem{id:line.target}) MERGE (s)-[:relation{relation:line.relation}]->(t);
注意,这种导入方式需要先启动 Neo4j 数据库
此外,若文件名称使用相对路径,则从配置文件指定的位置开始算,当然也可以使用绝对路径
2、批量导入
批量导入适用于超大型数据
可以使用 neo4j-import 或 neo4j-admin import 工具导入数据
但是现在 neo4j-import 已经过时,推荐使用 neo4j-admin import
neo4j-admin import 既可以导入 CSV 文件,也可以导入数据库文件
这由参数 --mode 指定,若其值为 csv (默认),则表示导入 CSV 文件
此时参数 --id-type 用于指定标识的类型,其可选值有 STRING (默认)、INTEGER 和 ACTUAL
参数 --nodes:Label1:Label2 用于指定节点文件,并可以添加可选的节点标签
参数 --relationships:RELATIONSHIP_TYPE 用于指定关系文件,并可以添加可选的关系类型
这两个参数的值可以包含多个文件,这些文件会拼接成一个大文件,但要注意拼接后的文件也要符合格式
如需指定多个节点文件和关系文件,可以使用多个 --nodes、--relationships 参数
如果参数 --mode 的值为 database,则表示导入数据库文件
这时参数 --from 用于指定数据库路径,例如是 data/database/graph.db
参数 --database 用于指定数据库名称,默认为 graph.db
数据示例:
poet.csv
(节点文件)
:ID(poet-id),:LABEL,name 0,poet,李白 1,poet,杜甫 2,poet,白居易 3,poet,王维 4,poet,李商隐 5,poet,苏轼 6,poet,辛弃疾 7,poet,李清照 8,poet,柳永 9,poet,陆游
poem.csv
(节点文件)
:ID(poem-id),:LABEL,name 0,poem,将进酒 1,poem,茅屋为秋风所破歌 2,poem,琵琶行 3,poem,使至塞上 4,poem,锦瑟 5,poem,定风波·莫听穿林打叶声 6,poem,永遇乐·京口北固亭怀古 7,poem,一剪梅·红藕香残玉簟秋 8,poem,雨霖铃·寒蝉凄切 9,poem,诉衷情·当年万里觅封侯
edge.csv
(关系文件)
:START_ID(poet-id),:END_ID(poem-id),:TYPE,relation 0,0,relation,作品 1,1,relation,作品 2,2,relation,作品 3,3,relation,作品 4,4,relation,作品 5,5,relation,作品 6,6,relation,作品 7,7,relation,作品 8,8,relation,作品 9,9,relation,作品
命令示例:
./bin/neo4j-admin import \ --mode csv \ --nodes ../poet.csv \ --nodes ../poem.csv \ --relationships ../edge.csv
注意,这种导入方式需要先关闭 Neo4j 数据库
此外,若文件名称使用相对路径,则从当前目录开始算,当然也可以使用绝对路径
实际上 neo4j-admin import 是用来创建一个新数据库的,它不能向现有数据库添加数据
如果用 neo4j-admin import 向一个已经有数据的数据库导入新数据,那么就会得到报错
这也是 neo4j-admin import 的一个弊端,不过解决报错的方法倒是挺简单的,有两个:
删除现存数据库,然后再重新导入数据
删除数据库的方法简单直接,直接删除数据库文件即可,默认位置在 data/database/graph.db
导入到新数据库,然后再启动该数据库
导入时可以通过 --database 参数指定新数据库名称,启动时可以通过配置文件指定新数据库