neo4j使用详解


安装neo4j

neo4j简介

Neo4j是一个基于JAVA编写的NoSQL数据库,相比于 MySQL 之类的关系数据库(RDBMS),能更灵活地表示数据,主要特点有:

  • 可以灵活地设计、扩展 schema
  • 适合表示实体之间的关系(特别是当实体之间存在大量、复杂的关系时)

Neo4j存储的图由顶点(节点node)、边(关系relationship)和属性(property)组成,顶点和边都可以设置属性(一个或多个),使用Cypher进行查询,同时支持scala、python等调用。

开发者可参考:nep4j developer

准备java环境

(如果机器有java环境,此步略)

在shell运行如下命令查看java版本

java -version

Neo4j基于Java环境,所以在安装neo4j之前先安装JAVA SE的JRE,去Oracle官网下载JDK(JDK包含JRE,JRE提供环境,JDK可以支持开发Java程序)。下载JAVA SDK

  • JAVA版本需要与Neo4j版本对应,我使用的neo4j版本4.2.2,使用的JAVA版本jdk-11.0.9

可以把JAVA JDK配置在环境变量也可以在运行时通过export指定(后面使用export指定的方法)。

安装neo4j

安装过程非常方便,下载tar包解压,按需修改config即可

下载neo4j,neo4j下载地址 ,社区版本是免费的,推荐。

下载完成后解压

tar -axvf neo4j-community-4.2.2-unix.tar.gz

修改相应配置

配置在conf/neo4j.conf,并不是全部都需要修改,看个人需要,我就改了一下端口(注:neo4j涉及三个端口),重点关注配置

# 修改第22行load csv时l路径,在前面加个#,可从任意路径读取文件
#dbms.directories.import=import

# 修改35行和36行,设置JVM初始堆内存和JVM最大堆内存
# 生产环境给的JVM最大堆内存越大越好,但是要小于机器的物理内存
dbms.memory.heap.initial_size=5g
dbms.memory.heap.max_size=10g

# 修改46行,可以认为这个是缓存,如果机器配置高,这个越大越好
dbms.memory.pagecache.size=10g

# 修改54行,去掉改行的#,可以远程通过ip访问neo4j数据库
dbms.connectors.default_listen_address=0.0.0.0

# 默认 bolt端口是7687,http端口是7474,https端口是7473,不修改下面3项也可以
# 修改71行,去掉#,设置http端口为7687,端口可以自定义,只要不和其他端口冲突就行
dbms.connector.bolt.listen_address=:7687

# 修改75行,去掉#,设置http端口为7474,端口可以自定义,只要不和其他端口冲突就行
dbms.connector.http.listen_address=:7474

# 修改79行,去掉#,设置http端口为7473,端口可以自定义,只要不和其他端口冲突就行
dbms.connector.https.listen_address=:7473

# 修改227行,去掉#,允许从远程url来load csv
dbms.security.allow_csv_import_from_file_urls=true

# 修改246行,允许使用neo4j-shell,类似于mysql 命令行之类的
dbms.shell.enabled=true

# 修改235行,去掉#,设置连接neo4j-shell的端口,一般都是localhost或者127.0.0.1,这样安全,其他地址的话,一般使用https就行
dbms.shell.host=127.0.0.1

# 修改250行,去掉#,设置neo4j-shell端口,端口可以自定义,只要不和其他端口冲突就行
dbms.shell.port=1337

# 修改254行,设置neo4j可读可写
dbms.read_only=false

启动

如果将JAVA配置在环境变量中,则可以直接运行start启动

bin/neo4j start  # 启动
bin/neo4j stop  # 停止
bin/neo4j restart  # 重启
bin/neo4j status  # 状态

如果JAVA没有配置在环境变量可以新建一个执行脚本,类似如下

export JAVA_HOME="/xxx/jdk-11.0.9"
export PATH=/xxx/neo4j-community-4.2.2/bin:/xxx/jdk-11.0.9/bin:$PATH

neo4j $*

设置密码

安装完Neo4j后 默认的初始用户名是:neo4j ,密码也是:neo4j

登录成功后,会要求重置 neo4j 密码,修改并确认新密码。也可以通过命令行修改密码,运行

./cypher-shell  # 命令, 输入用户名,密码(初始默认用户名和密码为 neo4j)
# 输入命令
CALL dbms.security.changePassword('123456'); 
# 输入命令
exit;  # 退出

数据导入

数据导入方法

neo4j提供create、load、insert、import、Neo4j-import 共计5总导入方法。

常见导入形式对比

CREATE语句 LOAD CSV语句 Batch Inserter Batch Import Neo4j-import
适用场景 1 ~ 1w nodes 1w ~ 10 w nodes 千万以上 nodes 千万以上 nodes 千万以上 nodes
速度 很慢 (1000 nodes/s) 一般 (5000 nodes/s) 非常快 (数万 nodes/s) 非常快 (数万 nodes/s) 非常快 (数万 nodes/s)
优点 使用方便,可实时插入。 使用方便,可以加载本地/远程CSV;可实时插入。 速度相比于前两个,有数量级的提升 基于Batch Inserter,可以直接运行编译好的jar包;可以在已存在的数据库中导入数据 官方出品,比Batch Import占用更少的资源
缺点 速度慢 需要将数据转换成CSV 需要转成CSV;只能在JAVA中使用;且插入时必须停止neo4j 需要转成CSV;必须停止neo4j 需要转成CSV;必须停止neo4j;只能生成新的数据库,而不能在已存在的数据库中插入数据。

此处给出Neo4j-import和load两种方法

Neo4j-import导入

这里默认库式neo4j,所以在使用Neo4j-import之前需要将neo4j-community-4.2.2/data/databases/neo4j 下的文件清空。

停止neo4j(neo4j stop)

需要准备将数据准备为CSV格式,实体Node数据格式如下:

关系数据格式如下

导入详细配置如下

neo4j-admin import [--mode=csv] [--database=]
                          [--additional-config=]
                          [--report-file=]
                          [--nodes[:Label1:Label2]=<"file1,file2,...">]
                          [--relationships[:RELATIONSHIP_TYPE]=<"file1,file2,...">]
                          [--id-type=]
                          [--input-encoding=]
                          [--ignore-extra-columns[=]]
                          [--ignore-duplicate-nodes[=]]
                          [--ignore-missing-nodes[=]]
                          [--multiline-fields[=]]
                          [--delimiter=]
                          [--array-delimiter=]
                          [--quote=]
                          [--max-memory=]
                          [--f=]
                          [--high-io=]

我使用用的命令如下

export JAVA_HOME="/xxx/jdk-11.0.9"
export PATH=/xxx/neo4j-community-4.2.2/bin:/xxx/jdk-11.0.9/bin:$PATH

neo4j-admin import --database=neo4j \
             --nodes ./data/node_ip.csv \
             --nodes ./data/node_mobile.csv \
             --nodes ./data/node_userid.csv \
             --relationships ./data/edge_mobile_userid.csv \
             --relationships ./data/edge_ip_mobile.csv \
             --relationships ./data/edge_ip_userid.csv \
             --skip-duplicate-nodes=true \
             --ignore-empty-strings=true

启动neo4j(neo4j start)即可。

load csv 导入

对于数据量千万以下,个人推荐使用load csv 方法,将数据转化为csv后,不用停止neo4j,灵活方便。

这里使用图的时候有一个需求:只查询近一段时间的关系数据,更早时间的不需要,采用的方法是例行化产生小时级划分的csv文件夹,按照load csv的方法,load指定文件夹的数据到neo4j中,更早时间的数据可以删除

创建节点

# 创建NodeIp node数据表
CREATE CONSTRAINT ON (i:NodeIp) ASSERT i.id IS UNIQUE;
LOAD CSV WITH HEADERS FROM 'file:///ppp/20210301/00/node_ip.csv' AS line FIELDTERMINATOR ','  
MERGE (:NodeIp { id:line.id ,name: line.name, lab: line.label});

# 创建NodeUserid node数据表
CREATE CONSTRAINT ON (i:NodeUserid) ASSERT i.id IS UNIQUE;
LOAD CSV WITH HEADERS FROM 'file:///ppp/20210301/00/node_userid.csv' AS line FIELDTERMINATOR ','  
MERGE (:NodeUserid { id:line.id ,name: line.name, lab: line.label});

创建边(neo4j的关系是任意的,所以方向可忽略)

LOAD CSV WITH HEADERS FROM "file:///ppp/20210301/00/edge_ip_userid.csv" AS line FIELDTERMINATOR ','
MATCH (from:NodeIp{id: line.startid}),(to:NodeUserid{id: line.endid}) MERGE (from)-[r:ip_userid {typ: line.typ, appname:line.appname, dtime:line.dtime, dt:line.dt, hour:line.hour}]->(to);

创建完成后如下

Cypher操作

CQL语言

CQL代表Cypher查询语言。 像Oracle数据库具有查询语言SQL,Neo4j具有CQL作为查询语言。详细可参考 neo4j教程

在创建节点和边的过程中已经使用过CREATE、MATCH、MERGE、LAOD等语句。

# NodeIp节点表,并显示前25行。
MATCH (n:NodeIp) RETURN n LIMIT 25;
# 加where条件
MATCH (IP:NodeIp) 
WHERE IP.name = 'xxx.xxx.xxx.xxx'
RETURN IP LIMIT 25;
# 删除节点
MATCH (IP:NodeIp) DELETE IP;
# 添加或更新属性值
MATCH (IP:NodeIp)
SET IP.name = 'xxx'
RETURN IP;
# 排序
MATCH (IP:NodeIp)
RETURN IP.name
ORDER BY IP.name DESC;
# in 运算符
MATCH (IP:NodeIp) 
WHERE IP.name IN ['xxx','xxx']
RETURN IP;

更多可参考 neo4j教程

完~


文章作者: Boole
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Boole !
评论
  目录