Neo4j 为多种语言提供了 API 接口,如 javapythonC#RUBY.NET等。本文首先介绍用 python 操作 Neo4j。

首先安装好py2neo库

sudo pip3 install py2neo
1. 连接数据库
from py2neo import Graph
# 连接本地的 Neo4j 数据库,地址为 127.0.0.1,http 端口默认为 7474,用户名和密码分别为 neo4j 与 123
graph = Graph(host='127.0.0.1', http_port=7474, user='neo4j', password='123')

2. 创建节点
from py2neo import Node
# 创建角色节点 郭靖,拥有属性 姓名-郭靖,性别-男
guojing = Node('角色',name='郭靖',sex='男')

3. 操作属性
# 获取key对应的属性
guojing['name']
# 设置 key 对应属性的value,如果key不存在就创建
huangrong['born'] = '桃花岛'
# 删除某个属性
del huangrong['born']
# 返回节点中 property 的个数
len(huangrong)

# 此时的节点已经创建在本地,但还没有上传到 Neo4j 数据库中,因此在 Neo4j 客户端中是没有任何内容的,所以接下来使用 Graph 中的 create 方法来上传数据。
graph.create(guojing)

在这里,如果重复 create 同一个节点,如

# 反复执行此命令来创建郭靖节点
graph.create(guojing)

# 重新 guojing 变量赋值
guojing = Node('角色',name='郭靖',sex='男')
guojing

实际上在 Neo4j 数据库中并不会重复创建,因为在上传 guojing 节点时,变量的 <id> 属性已经固定,所以不会重复。如果重新定义一个 guojing 节点。节点前的 <id> 属性被抹去,此时在上传,数据库中就会存在两个相同节点了,若要避免这种情况,就需要用到 Graph 中的 merge 方法了。

关系的操作和节点操作很类似:

4. 创建关系
from py2neo import Relationship
# 创建郭靖与黄蓉的配偶关系
spouse1 = Relationship(guojing,'配偶',huangrong)
# 创建黄蓉与郭靖的配偶关系
spouse2 = Relationship(huangrong,'配偶',guojing)
# 创建郭靖与射雕英雄传的所在作品关系
inbook1 = Relationship(guojing,'所在作品',shediao)
# 创建黄蓉与射雕英雄传的所在作品关系
inbook2 = Relationship(huangrong,'所在作品',shediao)
# 打印结果
spouse1,spouse2,inbook1,inbook2

# 设置 key 对应属性的 value
inbook1['role'] = '男主角'

# 删除某个属性
del inbook1['role']

# 创建黄蓉与射雕英雄传的所在作品关系
graph.create(inbook2)
5. 查找
from py2neo import NodeMatcher
# 初始化一个 matcher 实例
matcher = NodeMatcher(graph)
# 用 match 方法查找 角色中name为郭靖的节点,返回一个 NodeMatch 对象
result = matcher.match("角色", name="郭靖")
# first 方法返回查询结果的第一个
result.first()
# 通过 list 来把所有结果显示出来
list(result)

Graph 同时提供 run 方法来直接执行 Cypher 语句。

# cypher 语句,对已存在的郭靖节点,创建节点和关系 (郭靖)-[父]->(郭啸天)
query = "match (n) where n.name = '郭靖' create (n)-[:父]->(:角色{name:'郭啸天'})"
# 执行 cypher 语句
graph.run(query)

# run 方法返回的是游标 cursors,cursors 必须通过遍历来展示结果
# cypher 语句,查询并返回所有的节点
query = "match (n) return n"
# 执行 cypher 语句,获得返回结果
cursors = graph.run(query)
# 通过遍历的方式取出所有结果
for i in cursors:
    print(i)

以上讲述了 Neo4j 数据库的 python 驱动 py2neo 的基本使用方法,在实际应用中,由于 python 胶水语言的特性,py2neo 可以搭配其他库方便地对知识图谱进行创建。比如在数据集中存在重复数据的情况,可以先用 python 进行一遍去重,再提交,比用 Cypher 语言去重速度更快。然而需要向数据库中写入大量数据时,用 CREATE 一条一条创建是非常低效的,因此,下面将介绍如何批量导入数据。

常见导入方法总结如下表:

CREATE 语句

LOAD CSV 语句

Batch Inserter

Batch Import

Neo4j-admin import

适用场景

1 ~ 1 w nodes

1 w ~ 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-admin import 构建,Neo4j 官方提供了 neo4j-admin import 来解决数据量非常大时导入的性能瓶颈。

参数设置如下:

  • --nodes 节点所在 CSV 文件
  • --relationships 关系所在 CSV 文件

nodes 节点所在 CSV 文件格式形式如下

python py2neo python py2neo 绘制关系图_python py2neo

 第一列为 ID 号,在构建关系时必须用过 ID 号来对应关系,第二、三列为属性值,第四列为节点类型。

relationships 关系所在 CSV 文件格式形式如下

python py2neo python py2neo 绘制关系图_人工智能_02

第一列表示起始节点的 ID 号,第二列表示截至节点的 ID 号,第三列为关系类型。

在使用 neo4j-admin import 时,需要先 sudo neo4j stop 停止 Neo4j 服务,同时删除旧的 graph.db 文件(通过 neo4j.conf 可以知道在 /var/lib/neo4j/data/databases 目录下)。

$ ./neo4j-admin import --nodes=../import/nodes.csv --relationships=../import/relationships.csv

python py2neo python py2neo 绘制关系图_学习_03