neo4j 操作指南
安装 neo4j 数据库
1. 下载
进入 neo4j 官方网站的下载页面,根据所用操作系统,下载适当的版本。
因为企业版需要授权,因此可暂先下载社区版本,下面以 Linux 系统为例:
# 下载
$ wget https://neo4j.com/artifact.php?name=neo4j-community-3.4.1-unix.tar.gz
# 解压
$ tar zxvf ./neo4j-community-3.4.1-unix.tar.gz
2. 配置
下载并解压后得到的目录形如:
$ tree ./neo4j-community-3.4.1-unix
.
├── bin/ # <- 可执行程序
├── certificates/
├── conf/ # <- 配置文件
├── data/ # <- 数据库中的数据
├── import/
├── lib/
├── logs/
├── plugins/
├── run/
├── LICENSES.txt
├── LICENSE.txt
├── NOTICE.txt
├── README.txt
└── UPGRADE.txt
2.1 配置环境变量
配置环境变量 NEO4J_HOME
值为该目录的地址。还可将 bin
目录加入 PATH
。
2.2 设置数据库服务的地址与端口
打开 conf/neo4j.conf
文件,找到下面内容:
# Bolt connector
dbms.connector.bolt.enabled=true
#dbms.connector.bolt.tls_level=OPTIONAL
#dbms.connector.bolt.listen_address=:7687 <# neo4j 操作指南
# HTTPS Connector. There can be zero or one HTTPS connectors.
dbms.connector.https.enabled=true
#dbms.connector.https.listen_address=:7473 <---
打开上面箭头所指行的注释,并在冒号前加上本机的 ip 地址,如改为:
dbms.connector.https.listen_address=0.0.0.0:7687
3. 运行
运行 bin
目录下的 neo4j
命令。
$ sudo neo4j start
此时数据库系统已经启动了,如果遇到问题,可以查看 logs/
中的日志文件,定位错误。
neo4j 数据库数据导入指南
在初始化数据库的时候,通常需要导入大量的数据,此时需要采用一种批量导入的方法,而非一条条插入。下面内容描述了如何准备数据,以及如何将数据导入 neo4j 数据库中。
本文主要参考了 neo4j 的关于导入数据的文档 Use the Import tool ,并结合自己的实践经验做了些许说明。
neo4j 图数据库核心概念介绍
在关系型数据库中,如 MySql,数据以元组形式存储,多个同型元组构成表,表与表之间通过外键进行关联。在 neo4j 图数据库中,数据以节点(Node)存储,每个节点可以有各自的属性,节点间通过关系相连。
上图中,存在 3 个节点,其中 2 个 Person 节点,1 个 Movie 节点。节点各自包含自身的,Person 和 Movie 间通过 AVTED_IN
和 DIRECTED
连接。关系自身也可包含属性,比如 ACTED_IN
中包含了 roles 属性,指明 Person 在 Movie 中饰演什么角色。
数据导入主要思想
在图数据库中,核心有两个,即节点和关系。通常一个图数据库中会含多类节点,和连接这各类节点的关系。neo4j 提供了向数据库中导入海量数据的工具 neo4j-admin import,使用该工具导入数据,比使用插入语句要快很多。
该工具要求待导入数据以 csv 格式存储,节点与关系的数据需要按照约定的格式存储在 csv 文件中,neo4j 的导入工具读取并导入这些数据。
具体操作方法可以参考 Use the Import tool,或者阅读下面的简化版操作指南。
数据导入方法
1. 数据准备
构建数据库,第一步要确定存在哪些类型的节点,以及节点间有哪些关系。下面假想一个场景。
在人才招聘网站的图数据库中,可能包含 求职者
、公司
、职位
、简历
这四类节点。
四类节点通过以下关系相连:
- 求职者 –浏览–> 职位
- 求职者 –申请–> 职位
- 求职者 –创建–> 简历
- 公司 –发布–> 职位
要构建数据库,需要提供这些节点和关系对应的数据。
1.1 数据格式说明
neo4j
的导入工具要求数据以 csv
格式存储,且规定了一些特殊的格式。
csv 文件头部格式
一个 csv 文件中,通常存放的是同类数据,其中的每一行为一个元素,每一列为一个属性。文件的第一行为头部,记录了各列的属性名。
neo4j 导入工具对 csv 头部做了部分扩展。在其格式形如:
<field_name>:<field_type>, <field_name>:<field_type>, <field_name>:<field_type>
其中 <field_name>
为属性名,冒号后面的 <field_type>
指明该属性的类型。类型可忽略,默认会使用 string
类型。
因为 csv 中数据均以文本形式存储,<field_type>
是为了明确指明各个字段的数据类型。可选的类型如下:
int, long, float, double, boolean, byte, short, char,
string, point, date, localtime, time,localdatetime,
datetime, duration
举例如下:
用户编号:string, 简历编号, 简历编号, 简历名称, 性别, 年龄:int
6717, 18294R9, 4658, 销售主管, 男, 28
节点数据
每一类节点都有不同的属性,因此通常不同类型的节点会存放在不同的 csv 文件中。采用前面提到的格式,把节点数据整理为 csv 文件。而后,对于节点数据,需要对 csv 的头部再做适当扩展。
每一个节点,需要有一个 id 来标识。在 csv 文件头部需要有一个特殊的 ID
类型的字段,该字段的值在当前文件中要唯一。
另外,每个节点都有其标签。通过增加一个类型为 LABEL
的列来指明节点标签。
举例如下 applicants.csv
:
用户编号:ID, age:int,gender:string,:LABEL
1698,27,'女',求职者
1699,23,'女',求职者
在 applicants.csv
文件中,用户编号:ID
指明以用户编号作为节点的 id。最后一列,:LABEL
,指明了节点的标签。
关系数据
一个关系最基本的要素为:关系名、关系起点、关系终点。在记录关系数据的 csv 文件的头部,至少要指出这三种信息。
以 browse.csv
为例:
用户编号:START_ID,职位编号:END_ID,:TYPE
1699,3122,浏览
START_ID
指出关系的起始结点的 id,END_ID
指出关系的终点的 id,而 TYPE
指出关系类型。这里的 START_ID
与 END_ID
的值均对应一个节点的 ID。
上面这一条数据,就给 id 为 1699
的用户和编号为 3122
的职位间建立了 浏览 的关系。
补充说明
如果不同的节点有相同的 id,比如节点 id 按行递增时,这个时候在关系数据中 START_ID
与 END_ID
所指就不唯一了。解决方法是给 ID 增加命名空间。
用户编号:ID(USER_ID), age:int,gender:string,:LABEL
1698,27,'女',求职者
职位编号:ID(JOB_ID), 职位名称,:LABEL
3122,C++工程师,职位
用户编号:START_ID(USER_ID),职位编号:END_ID(JOB_ID),:TYPE
1699,3122,浏览
这里使用类似 ID(USER_ID)
的写法,为不同节点的 ID 定义了命名空间,这样以来不同节点间相同的 ID 也就不会冲突了。
2. 导入数据
neo4j 提供了命令行工具来完成大量数据导入,其可执行文件为 <neo4j_home>/bin/neo4j-admin
。其中 <neo4j_home>
为 neo4j 的安装目录。
可以通过下面的命令导入数据:
$ neo4j-admin import \
--nodes=applicants.csv --nodes=job.csv \ # 指定节点文件
--relationships=browse.csv --relationships=deliver.csv \ # 指定关系文件
--delimiter=";" \ # 指定 csv 的分隔符,默认为英文逗号 (,)
--array-delimiter="|" \ # csv 文件中某个字段为数组时,数组元素间的分隔符
即通过 --nodes
和 --relationships
选项,将结点和关系对应的 csv 文件传给导入工具。
neo4j-admin import
命令有很多的参数,具体可以参见 文档 1 和 文档 2。
使用导入工具
如果需要要导入的文件很多,命令行就会很长。这里提供了一段 python 脚本,通过编写配置文件,生成相应的命令并执行,以缓解输入很长命令的麻烦。
import.py
可以在此处获得。
用法如下:
$ python import.py config.json
其中 config.json
为配置文件,文件格式如下:
{
"neo4j_home": "/home/xx/neo4j-community",
"database": "graph.db", // 指定数据库名,默认为 `graph.db`
"nodes": [{ // 指定节点对应的 csv 文件
"header": "./data/user_header.csv",
"file": "./data/user.csv",
"labels": ["USER"]
},{
"file": "./data/job.csv",
}],
"relationships": [{ // 指定关系对应的 csv 文件
"file": "./data/browse.csv",
"types": ['BROWSE']
}],
"delimiter": ",",
"array-delimiter": ";",
"quote": "\"",
"ignore-duplicate-nodes": true,
"ignore-missing-nodes": true
}
各字段说明如下:
=> neo4j_home
此字段用于指定 neo4j 的主目录,便于定位可执行文件 neo4j-admin
的位置。
=> nodes / relationships
提供节点和关系的数据。
labels/types
:
在节点和关系对应的 csv 文件中,可以不添加 :LABEL
或者 :TYPE
列,而在配置文件中使用 labes
或 types
指出。因为一个节点可以有多种 label,相似地一个关系也可以有多个 type,因此这里使用数组。
header
:
CSV 文件含两个部分,header 和 body,可以将 header 部分单独放在一个文件中。
=> delimiter
指定 csv 的列分隔符,默认为英文逗号 (,
)。
=> array-delimiter
csv 文件中某个字段为数组时,数组元素间的分隔符。在生成 CSV 文件的时候,某个属性是数组,将其元素使用 array-delimiter
指定的字符拼接起来,在读入 neo4j 之后,该字段依然能被识别为数组。
=> quote
在 csv 文件中,某个字段的内容中出现了 delimiter
,这会导致某一行列数增加,csv 格式就会出错。解决的办法是,将此字段使用 quote 括起来。括起来的内容,出现 delimiter
不会被解释为列分隔符。
因此这里的 quote
需要根据生成 CSV 时的设置来决定。
=> ignore-duplicate-nodes
是否忽略重复的节点,即 ID 重复的是否忽略,默认为 false。
=> ignore-missing-nodes
某个关系指定的节点不存在时,是否忽略该条关系。如果不忽略,就会报错。默认为 false,即不忽略。
其他技巧
在一台机器上启动多个实例
=> 1. 将 neo4j 拷贝一份
cp ./neo4j-community-3.4.0/ ./project/neo4j-community-3.4.0/
=> 2. 修改配置文件
修改端口至一个未使用的端口,参考前文 neo4j 数据库安装指南
vim ./project/neo4j-community-3.4.0/conf/neo4j.conf
=> 3. 配置环境变量
将环境变量 NEO4J_HOME
临时指向新的 neo4j 代码包的拷贝。因为在导入数据的时候,和启动 neo4j 的时候,需要使用此环境变量。
export NEO4J_HOME="path-to-neo4j-dir"
=> 4. 导入数据
=> 5. 启动
./neo4j-community-3.4.0/bin/neo4j start