Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

neo4j 操作指南 #51

Open
w4096 opened this issue Feb 27, 2019 · 3 comments
Open

neo4j 操作指南 #51

w4096 opened this issue Feb 27, 2019 · 3 comments

Comments

@w4096
Copy link
Owner

w4096 commented Feb 27, 2019

@w4096
Copy link
Owner Author

w4096 commented Feb 27, 2019

安装 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  <---

# HTTP Connector. There must be exactly one HTTP connector.
dbms.connector.http.enabled=true
#dbms.connector.http.listen_address=:7474 <---

# 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/ 中的日志文件,定位错误。

@w4096
Copy link
Owner Author

w4096 commented Feb 27, 2019

neo4j 数据库数据导入指南

在初始化数据库的时候,通常需要导入大量的数据,此时需要采用一种批量导入的方法,而非一条条插入。下面内容描述了如何准备数据,以及如何将数据导入 neo4j 数据库中。

本文主要参考了 neo4j 的关于导入数据的文档 Use the Import tool ,并结合自己的实践经验做了些许说明。

neo4j 图数据库核心概念介绍

在关系型数据库中,如 MySql,数据以元组形式存储,多个同型元组构成表,表与表之间通过外键进行关联。在 neo4j 图数据库中,数据以节点(Node)存储,每个节点可以有各自的属性,节点间通过关系相连。

上图中,存在 3 个节点,其中 2 个 Person 节点,1 个 Movie 节点。节点各自包含自身的,Person 和 Movie 间通过 AVTED_INDIRECTED 连接。关系自身也可包含属性,比如 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_IDEND_ID 的值均对应一个节点的 ID。

上面这一条数据,就给 id 为 1699 的用户和编号为 3122 的职位间建立了 浏览 的关系。

补充说明

如果不同的节点有相同的 id,比如节点 id 按行递增时,这个时候在关系数据中 START_IDEND_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 脚本,通过编写配置文件,生成相应的命令并执行,以缓解输入很长命令的麻烦。

https://github.com/wy-ei/py/blob/master/neo4j/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 列,而在配置文件中使用 labestypes 指出。因为一个节点可以有多种 label,相似地一个关系也可以有多个 type,因此这里使用数组。

  • header:

CSV 文件含两个部分,header 和 body,可以将 header 部分单独放在一个文件中。如果 csv 文件的第一行就是 header,那就不需要指定 header 字段了。只需要配置 file 即可。

=> 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,即不忽略。

@w4096
Copy link
Owner Author

w4096 commented Feb 27, 2019

其他技巧

在一台机器上启动多个实例

=> 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 的时候,需要使用此环境变量。

因为环境变量只在程序启动的时候会被读取,当数据库启动后,此环境变量就可以随意修改了。因此启动不同是 neo4j 的实例时,修改环境变量 NEO4J_HOME 为不同的目录就可以了。

export NEO4J_HOME="path-to-neo4j-dir"

=> 4. 导入数据

=> 5. 启动

./neo4j-community-3.4.0/bin/neo4j start

@w4096 w4096 transferred this issue from another repository Feb 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant