Neo4j图数据库及Cypher语法基础

  1. 1.前言
    1. 1.1 图数据库概述
      1. 1.1.1 图数据库的现实背景
      2. 1.1.2 什么是图数据库
      3. 1.1.3 与关系型数据库的对比
      4. 1.1.4 图数据库的应用场景
      5. 1.1.5 比较流行的图数据库
    2. 1.2 Neo4j图数据库概述
      1. 1.2.1 Neo4j简介
      2. 1.2.2 Neo4j的优势
      3. 1.2.3 Neo4j的版本
      4. 1.2.4 Neo4j基本概念
    3. 1.3 Cypher查询语言概述
      1. 1.3.1 Cypher简介
      2. 1.3.2 Cypher组成结构
      3. 1.3.3 Cypher基本命令
    4. 1.4 知识图谱概述
      1. 1.4.1 知识图谱简介
      2. 1.4.2 知识图谱体系架构
  2. 2. 搭建Neo4j服务
    1. 2.1 准备Docker环境
    2. 2.2 使用Docker搭建Neo4j服务
      1. 2.2.1 拉取镜像并运行容器
      2. 2.2.2 修改Neo4j配置文件
      3. 2.2.3 Neo4j的可视化管理
  3. 3. Neo4j数据导入
    1. 3.1 Neo4j导入数据的方式
    2. 3.2 使用 Cypher Load CSV 语句导入数据
      1. 3.2.1 CSV文件格式要求
      2. 3.2.2 官方导入示例
  4. 4. 使用Python操作Neo4j
  5. 5. Cypher基本语法
    1. 5.1 基本类型
      1. 5.1.1 数据类型
      2. 5.1.2 数值类型算术运算
      3. 5.1.3 字符串类型常用函数
      4. 5.1.4 节点和关系
      5. 5.1.5 列表
    2. 5.2 CREATE 命令
      1. 5.2.1 创建节点
      2. 5.2.2 创建关系
      3. 5.2.3 混合使用
      4. 5.2.4 SET 子句
      5. 5.2.5 MERGE 命令
      6. 5.2.6 FOREACH 函数
    3. 5.3 DELETE 删除和 REMOVE 删除
      1. 5.3.1 删除属性
      2. 5.3.2 删除节点和边
      3. 5.3.3 清空数据库
    4. 5.4 匹配语句
      1. 5.4.1 根据标签匹配节点
      2. 5.4.2 根据标签和属性匹配节点
      3. 5.4.3 匹配任意关系
      4. 5.4.4 可选匹配
      5. 5.4.5 过滤匹配
      6. 5.4.6 路径长度匹配
      7. 5.4.7 SHORTESTPATH 函数
  6. 6. 使用Neovis.js将Neo4j前端可视化
  7. 7. 参考资料

1.前言

1.1 图数据库概述

1.1.1 图数据库的现实背景

现实中很多数据都是用图来表达的,比如社交网络中人与人的关系、地图数据或是基因信息等等。RDBMS并不适合表达这类数据,而且由于海量数据的存在,让其显得捉襟见肘。NoSQL数据库的兴起,很好地解决了海量数据的存放问题,图数据库也是NoSQL的一个分支,相比于NoSQL中的其他分支,它很适合用来原生表达图结构的数据。

1.1.2 什么是图数据库

图数据库是基于图论实现的一种新型NoSQL数据库,其数据库存储结构和数据的查询方式都是以图论为基础的。图论中图的基本元素为节点和边,在图数据库中对应的就是节点和关系。

图数据库

1.1.3 与关系型数据库的对比

与传统关系型数据库相比,图数据库的优势有:

  • 可以很自然的表达现实世界中的实体及其关联关系(对应图的顶点及边);
  • 灵活的数据模型可以适应不断变化的业务需求;
  • 灵活的图查询语言,轻松实现复杂关系网络的分析;
  • 关系型数据库在遍历关系网络并抽取信息的能力非常弱,图数据库则为此而生;
  • 关系型数据库在数据规模庞大时很难做多层关联关系分析(Join操作往往消耗过长时间而失败),图数据库则天然把关联数据连接在一起,无需耗时耗内存的Join操作,可以保持常数级时间复杂度。

1.1.4 图数据库的应用场景

世界上很多著名的公司都在使用图数据库,比如:

  • 社交领域:Facebook, Twitter,Linkedin用它来管理社交关系,实现好友推荐。
  • 零售领域:eBay,沃尔玛使用它实现商品实时推荐,给买家更好的购物体验。
  • 金融领域:摩根大通,花旗和瑞银等银行在用图数据库做风控处理。
  • 汽车制造领域:沃尔沃,戴姆勒和丰田等顶级汽车制造商依靠图数据库推动创新制造解决方案。
  • 电信领域:Verizon, Orange等电信公司依靠图数据库来管理网络。
  • 酒店领域:万豪和雅高酒店等顶级酒店公司依使用图数据库来管理复杂且快速变化的库存。

图数据库典型查询示例:

  • 多层关联:查询一个人的好友的好友有哪些。
  • 最短路径:查询两个点之间的最短路径。
  • 连通子图:查询一个点在K步以内相连接的所有邻接点(K=1,2,3…)。
  • 协同推荐:查询一个人的好友里面,哪些人喜欢哪些东西,然后把那些东西推荐给这个人。
  • 集中度测量:如PageRank、PersonalRank、特征向量集中度、亲密度等。

1.1.5 比较流行的图数据库

图数据库排名:https://db-engines.com/en/ranking/graph+dbms

图数据库比较:从左到右依次是Neo4j、OrientDB、ArangoDB、JanusGraph、HugeGraph、Dgraph、TigerGraph

图数据库比较

1.2 Neo4j图数据库概述

1.2.1 Neo4j简介

Neo4j是一个高性能的NoSQL图形数据库,它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中。 Neo4j也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有特性。

1.2.2 Neo4j的优势

  • 在创建节点的时候就已经把关系给建立起来,避免了在复杂查询场景下的处理。
  • 由于底层直接以图的形式存储节点和关系,在查询的时候可以使时间复杂度保持在常数级别。
  • 基于JVM实现。
  • 提供一套易于理解的查询语言Cypher以及内置的可视化UI。
  • 很好的支持ACID,有事务机制。

1.2.3 Neo4j的版本

Neo4j分三个版本:社区版(community)、高级版(advanced)和企业版(enterprise)。

  • 社区版是基础,它使用的是GPLv3协议,这意味着修改和使用其代码都需要开源,但是这是建立在软件分发的基础上,如果使用Neo4j作为服务提供,而不分发软件,则不需要开源。
  • 高级版和企业版建立在社区版的基础上,但多出一些高级特性,高级版包括一些高级监控特性。
  • 企业版则包括在线备份、高可用集群以及高级监控特性。要注意它们使用了AGPLv3协议,也就是说,除非获得商业授权,否则无论以何种方式修改或者使用Neo4j,都需要开源。

1.2.4 Neo4j基本概念

以下介绍常用的Neo4j基本概念,详见官方文档:https://neo4j.com/docs/getting-started/current/graphdb-concepts/

Neo4j创建的图(Graph)基于属性图模型,在该模型中,每个实体都有ID(Identity)唯一标识,每个节点由标签(Label)分组,每个关系都有一个唯一的类型,属性图模型的基本概念有:

[1] 实体(Entity):是指节点(Node)和关系(Relationship)

  • 每个实体都有一个唯一的ID;
  • 每个实体都有零个、一个或多个属性,一个实体的属性键是唯一的;
  • 每个节点都有零个、一个或多个标签,属于一个或多个分组;
  • 每个关系都只有一个类型,用于连接两个节点。

[2] 路径(Path):是指由起始节点和终止节点之间的实体(节点和关系)构成的有序组合。

[3] 标记(Token):是非空的字符串,用于标识标签(Label),关系类型(Relationship Type),或属性键(Property Key)。

  • 标签:用于标记节点的分组,多个节点可以有相同的标签,一个节点可以有多个标签,标签用于对节点进行分组;
  • 关系类型:用于标记关系的类型,多个关系可以有相同的关系类型;
  • 属性键:用于唯一标识一个属性。

[4] 属性(Property):是一个键值对,每个节点或关系可以有一个或多个属性,属性值可以是标量类型或者标量类型的列表(数组)。

1.3 Cypher查询语言概述

1.3.1 Cypher简介

Cypher 是 Neo4j 提出的图查询语言,是一种声明式的图数据库查询语言,它拥有精简的语法和强大的表现力,能够精准且高效地对图数据进行查询和更新。它是一种受 SQL 启发的语言,它允许声明想要从图数据库中选择、插入、更新或删除什么,而不需要精确地描述如何做到这一点。通过 Cypher,用户可以构建表达性强且高效的查询,处理所需的创建、读取、更新和删除功能。

1.3.2 Cypher组成结构

Cypher 的焦点在于从图中如何找回,而不是怎么去做,这个查询语言包含以下几个明显的部分:

  • START:在图中的开始点,通过元素的ID或所以查找获得。
  • MATCH:图形的匹配模式,束缚于开始点。
  • WHERE:过滤条件。
  • RETURN:返回所需要的。

1.3.3 Cypher基本命令

Cypher 基本命令总结如下表:

Cypher基本命令

Cypher 更具体的用法,下文会进行具体介绍,也可以参考 官方API文档

1.4 知识图谱概述

1.4.1 知识图谱简介

知识图谱是结构化的语义知识库,用于迅速描述各个事物的概念及其相互关系。 知识图谱对无结构的数据通过进一步处理和整合,转化成“实体-关系-实体”的三元组结构形式,聚合大量知识,进而实现知识的快速推理和响应。 随着智能信息化的不断发展,知识图谱已被广泛应用于智能搜索、智能问答、大数据分析与决策等领域。

1.4.2 知识图谱体系架构

知识图谱的体系架构是指其构建模式的结构,如下图所示:

知识图谱体系架构

2. 搭建Neo4j服务

以下我将采用Docker的方式进行搭建,VPS系统用的是Debian 11 x86_64。VPS的购买及配置、Docker的概念及使用…这些基本的就不再赘述了,如果不会的话见我的另一篇博客:VPS基本部署环境的搭建与配置

2.1 准备Docker环境

1
2
3
4
$ apt-get update -y && apt-get install curl -y  # 安装curl
$ curl https://get.docker.com | sh - # 安装docker
$ sudo systemctl start docker # 启动docker服务
$ docker version # 查看docker版本(客户端要与服务端一致)

2.2 使用Docker搭建Neo4j服务

2.2.1 拉取镜像并运行容器

1
2
3
$ docker pull neo4j
$ docker run -d --name neo4j -p 7474:7474 -p 7687:7687 -v /root/docker/neo4j/data:/data -v /root/docker/neo4j/logs:/logs -v /root/docker/neo4j/conf:/var/lib/neo4j/conf -v /root/docker/neo4j/import:/var/lib/neo4j/import --env NEO4J_AUTH=neo4j/neo4jpassword neo4j
$ docker update neo4j --restart=always

2.2.2 修改Neo4j配置文件

由于配置文件先前已经设置了挂载,因此在容器外的挂载目录进行修改即可:

1
$ vim /root/docker/neo4j/conf/neo4j.conf

配置文件示例如下(具体可以根据自己需求进行配置):

1
2
3
4
dbms.tx_log.rotation.retention_policy=100M size
dbms.memory.pagecache.size=512M
dbms.default_listen_address=0.0.0.0
dbms.directories.logs=/logs

2.2.3 Neo4j的可视化管理

浏览器打开http://IP:7474/browser/ 查看即可,7687端口是用来连接neo4j服务的。

neo4j连接

连接成功后,我们就可以在这里的输入框输入Cypher语句对Neo4j进行操作了,同时也可以在这个面板里进行可视化查看。

neo4j命令界面

3. Neo4j数据导入

3.1 Neo4j导入数据的方式

Neo4j导入数据有如下几种方式:

  • Cypher Creater语句,即通过语句创建导入,每一条数据写一个Create。

  • Cypher Load CSV语句,将数据转成CSV格式,通过 Load CSV 读取数据。

  • 官方提供的 neo4j-import 工具,现在被 neo4j-admin import 代替。

  • 大牛编写的 batch-import 工具,相比于官方导入工具在使用内存和增量导入上做了优化。

几种导入方式的对比:

Neo4j导入数据的方式对比

3.2 使用 Cypher Load CSV 语句导入数据

使用 Cypher Load CSV 语句导入数据,详见官方文档:https://neo4j.com/docs/cypher-manual/current/clauses/load-csv/

3.2.1 CSV文件格式要求

要使用的 CSV 文件LOAD CSV必须具有以下特征:

  • 字符编码为 UTF-8;
  • 结束行终止取决于系统,例如,它\n在 unix 或\r\nwindows 上;
  • 默认字段终止符是,;
  • FIELDTERMINATOR可以使用命令中的可用选项更改字段终止符LOAD CSV;
  • CSV 文件中允许使用带引号的字符串,并且在读取数据时会删除引号;
  • 字符串引用的字符是双引号”;
  • ifdbms.import.csv.legacy_quote_escaping设置为 , 的默认值true,\用作转义字符;
  • 双引号必须在带引号的字符串中并使用转义字符或第二个双引号进行转义。

3.2.2 官方导入示例

1
LOAD CSV FROM 'https://data.neo4j.com/bands/artists.csv' AS line CREATE (:Artist {name: line[1],year: toInteger(line[2])})

neo4j导入数据

4. 使用Python操作Neo4j

py2neo 是一个连接到 neo4j 数据库的 python 库,它不仅让程序本身可以直接执行 cypher 语句创建图数据库,也提供了人性化的操作。

依赖安装:

1
$ pip3 install py2neo

测试脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# -*- coding: utf-8 -*-

from py2neo import Graph
from py2neo import Node
from py2neo import Relationship
from py2neo import NodeMatcher

print("===Step1:连接 Neo4j 数据库")
graph = Graph('http://127.0.0.1:7474', auth=('neo4j', 'neo4jpassword'))

print("===Step2:创建节点")
# 从 py2neo 库中导入 Node 类,并通过 Node 类来创建节点实例
guojing = Node('角色', name='郭靖', sex='男')
huangrong = Node('角色', name='黄蓉', sex='女')
shediao = Node('作品', name='射雕英雄传', author='金庸')

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

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

print("===Step5:创建关系")
spouse1 = Relationship(guojing, '配偶', huangrong)
spouse2 = Relationship(huangrong, '配偶', guojing)
inbook1 = Relationship(guojing, '所在作品', shediao)
inbook2 = Relationship(huangrong, '所在作品', shediao)

print("===Step6:对关系进行操作")
# 设置 key 对应属性的 value
inbook1['role'] = '男主角'
print(inbook1)
# 删除某个属性
del inbook1['role']
print(inbook1)

print("===Step7:将关系上传到neo4j数据库")
# 与创建节点同理,用 create 将关系上传到数据库中。
graph.create(spouse1)
graph.create(spouse2)
graph.create(inbook1)
graph.create(inbook2)

print("===Step8:使用 NodeMatcher 来进行图的查找")
# 初始化一个 matcher 实例
matcher = NodeMatcher(graph)
# 用 match 方法查找 角色 中 name 为郭靖的节点,返回一个 NodeMatch 对象
result = matcher.match("角色", name="郭靖")
# first 方法返回查询结果的第一个
print(result.first())
# 通过 list 来把所有结果显示出来
print(list(result))

print("===Step9:使用 cypher 语句进行操作")
# 使用 cypher 语句,对已存在的 郭靖 节点,创建节点和关系 (郭靖)-[父]->(郭啸天)
query = "match (n) where n.name = '郭靖' create (n)-[:父]->(:角色{name:'郭啸天'})"
graph.run(query)
# cypher 语句查询,通过遍历的方式取出所有结果
query = "match (n) return n"
cursors = graph.run(query)
for i in cursors:
print(i)

控制台结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
===Step1:连接 Neo4j 数据库
===Step2:创建节点
===Step3:对节点进行操作
郭靖
(:角色 {born: '\u6843\u82b1\u5c9b', name: '\u9ec4\u84c9', sex: '\u5973'})
(:角色 {name: '\u9ec4\u84c9', sex: '\u5973'})
2
===Step4:将节点上传到neo4j数据库
===Step5:创建关系
===Step6:对关系进行操作
(郭靖)-[:所在作品 {role: '\u7537\u4e3b\u89d2'}]->(射雕英雄传)
(郭靖)-[:所在作品 {}]->(射雕英雄传)
===Step7:将关系上传到neo4j数据库
===Step8:使用 NodeMatcher 来进行图的查找
(_28:角色 {name: '\u90ed\u9756', sex: '\u7537'})
[Node('角色', name='郭靖', sex='男')]
===Step9:使用 cypher 语句进行操作
Node('角色', name='郭靖', sex='男')
Node('角色', name='黄蓉', sex='女')
Node('作品', author='金庸', name='射雕英雄传')
Node('角色', name='郭啸天')

面板结果:

使用Python操作Neo4j

5. Cypher基本语法

5.1节对Cypher进行基本介绍,不需要测试数据;5.2-5.3节对Neo4j进行增删改操作,用第3节导入的数据;5.4节对Neo4j进行查询操作,用第4节添加的数据。

5.1 基本类型

Cypher 中有以下几种基本类型:数值、字符串、布尔、节点、关系、列表

5.1.1 数据类型

Cypher 中的数据类型如下:boolean 用于表示布尔值、byte 用于表示 8 位整数、short 用于表示 16 位整数、int 用于表示 32 位整数、long 用于表示 64 位整数、float 用于表示 32 位浮点数、double 用于表示 64 位浮点数、char 用于表示 16 位字符、string 用于表示字符串

5.1.2 数值类型算术运算

数值类型支持的常用算术运算有:+加法运算、-减法运算、*乘法运算、/除法运算、%取余运算、^幂运算

1
2
// 执行算术运算,用 return 返回结果,不同运算用 , 隔开
return 1+1,1.2-3,100000*1000,100/200,3%4,2^10,True,false

Cypher算术运算

5.1.3 字符串类型常用函数

字符串类型支持的常用函数有:

  • toUpper:用于将所有字母更改为大写字母
  • toLower:用于将所有字母改为小写字母
  • substring:用于获取给定 String 的子字符串
  • replace:用于替换一个字符串的子字符串
  • split:用于切分字符串
  • +:用于字符串拼接
1
2
// 执行字符串函数,用 return 返回结果,不同运算用 , 隔开
return toUpper('a'),toLower('A'),substring('abcdefghijk',1,3),replace('abcde','ab','de'),split('abc,def',','),'1'+'2'

Cypher字符串类型函数处理

5.1.4 节点和关系

节点:Cypher 采用一对圆括号 () 来表示节点,如 (n:角色) 表示一个 角色 节点,n 是变量名,供命令执行时用 n 来访问这个节点,在命令执行完毕后就无法使用了。同时单独的 () 表示一个匿名节点,在匹配时表示匹配所有节点。

关系:可以表示无向关系和有向关系

1
2
3
4
--  表示无方向的关系
--> 表示有方向的关系
-[r]-> 则给关系赋予一个变量名,方便对这个关系进行操作
-[r:配偶]-> 匹配关系为 配偶 的类型

同时为了书写简单,可以为节点和关系语法赋予一个变量,这样变量 p 就可以写到多个查询语句中,避免重复编写。

1
2
// 将所有 (角色)-[配偶]-() 的子图赋值给变量 p
p = (n:角色)-[r:配偶]-()

5.1.5 列表

Cypher 支持列表操作,并且和 Python 中的列表很相似。通过 [] 来创建列表,列表中可以包含不同的元素。Cypher 同样支持列表推导,列表中用符号 | 隔开,前面的是列表元素,后面的是表达式。

1
2
3
4
// 执行列表操作,用 return 返回结果
return [1,'1',True,'1'+'2']
// 对 1-3 的数做除以 2 的操作
return [x in [1,2,3] | x/2]

Cypher列表操作

5.2 CREATE 命令

在 Neo4j 中,CREATE 命令用于创建节点和关系。

5.2.1 创建节点

CREATE 创建单个节点语法如下:

1
2
3
4
5
6
7
8
CREATE (
<node-name>:<lable-name>
{
<Property1-name>:<Property1-value>
......
<Propertyn-name>:<Propertyn-value>:
}
)

node-name 是要创建的节点名称,label-name 是节点标签名称。 Property-name 和 Property-value 分别是节点的属性值的 key-value 对。

如创建一个 金轮法王 节点,即在 label 为 角色的节点中创建一个 name金轮法王 的节点,同时为这个节点拥有来自 蒙古 的属性。

1
2
// 创建 角色 节点,拥有属性 name-金轮法王,from-蒙古
CREATE (n:角色 {name:'金轮法王',from:'蒙古'})

但在进行这个操作后,视图界面并不返回 Graph 界面,因为 CREATE 命令可以允许不跟 RETURN 同时使用,若使用了 RETURN,才会返回 Graph 界面。

Cypher创建节点

5.2.2 创建关系

CREATE 创建单个关系到节点语法如下:

1
2
3
CREATE (<node1-name>:<lable1-name>)-
[(relationship-name:<relationship-label-name>)]
->(<node2-name>:<lable2-name>)

Neo4j 只支持有向图,node1-name 为出节点,node2-name 为入节点, relationship-name 为关系的名称,relationship-label-name 为关系的标签名称。

1
2
3
CREATE (n:角色{name:'王重阳',nickname:'中神通'})-
[:师弟]
->(m:角色{name:'周伯通',nickname:'老顽童'})

Cypher创建关系

5.2.3 混合使用

因为存在两个内容完全相同的节点,因此,要给已经存在的两个节点创建关系,则不能简单地使用 CREATE 命令,而是要先用 MATCH 找到已存在的节点,再构建关系。

如要创建 EuropeRoxette 的关系,则先要找到 EuropeRoxette 这两个节点,再向这两个节点之间添加关系。

1
match (n:Artist),(m:Artist) where n.name='Roxette' and m.name='Europe' create (n)-[:国籍]->(m)

Cypher混合使用创建关系

5.2.4 SET 子句

SET 用于给现有节点或关系添加新属性,因此,SET 需要配合 MATCH 使用。 如给 ABBA 节点增加一个 “乐队” 属性

1
match (n:Artist) where n.name='ABBA' set n.type='乐队' return n

Cypher添加属性

5.2.5 MERGE 命令

MERGE 命令是 CREATE 命令和 MATCH 命令的组合。 MERGE 在图中搜索给定模式,如果存在,则返回结果,如果不存在,则创建并返回结果。

1
2
3
4
// 不存在,会添加
merge (n:门派{name:'少林'}) return n
// 已存在,不会添加
merge (n:Artist{name:'ABBA'}) return n

5.2.6 FOREACH 函数

foreachCypher 中列表的更新工具,在 foreach 中,支持 create,merge,deleteforeach 对图进行修改。

1
2
// 从字符串文本中创建 角色 节点
foreach(name in split('郭靖,杨过,张无忌',',') | create(n:角色{name:name})) return n

Cypher使用FOREACH批量操作

5.3 DELETE 删除和 REMOVE 删除

Neo4j 中有两种删除方法,DELETEREMOVEDELETE用于删除节点和关系,REMOVE 用于删除节点和关系的标签与属性。两者都需要配合 MATCH ,先匹配到内容,再执行操作。

5.3.1 删除属性

REMOVE金轮法王from 属性删除。

1
match (n:角色) where n.name='金轮法王' remove n.from return n

Cypher删除属性

5.3.2 删除节点和边

若要删除节点,则需要删除与节点相关的所有边,这与图论一致——不存在没有节点的边。 因此要删掉王重阳这个节点,就先需要找到该节点和所在关系,再进行删除。

1
match (n:角色)-[r]-() where n.name='王重阳' delete n,r

删除节点和边

5.3.3 清空数据库

要清空数据库,意味着要清空所有的节点和边节点存在两种情况:有边连接的和孤立的节点,因此需要同时匹配这两种情况,再进行删除。

1
match (n) optional match (n)-[r]-() delete n,r

Cypher清空数据库

5.4 匹配语句

在 Neo4j 中,MATCH 命令用于从数据库中获取节点,关系的信息,类似于 SQL 中的 SELECTRETURN 则是在 MATCH 搜索完成后返回数据,因此 MATCH 必须与 RETURN 同时使用。

5.4.1 根据标签匹配节点

1
2
// 匹配所有 角色 节点
match (n:角色) return n

Cypher根据标签匹配节点

5.4.2 根据标签和属性匹配节点

1
2
// 匹配 name 为 郭靖 的 角色 节点
match (n:角色{name:'郭靖'}) return n

Cypher根据标签和属性匹配节点

5.4.3 匹配任意关系

1
2
// 匹配出有任意关系的两个节点
match p = (n)-[r]->(m) return p

Cypher匹配任意关系

5.4.4 可选匹配

optional match 类似于 match,不同之处在于 optional match 在匹配不到内容时返回 null 方便查询继续进行,而 match 直接返回查询无结果。

1
2
3
4
// 用 match 匹配 郭靖 是否有关系到 倚天屠龙记
match p=(n:角色{name:'郭靖'})-[r]->(:作品{name:'倚天屠龙记'}) return p
// 用 optional match 匹配 郭靖 是否有关系到 倚天屠龙记
optional match p=(n:角色{name:'郭靖'})-[r]->(:作品{name:'倚天屠龙记'}) return p

Cypher可选匹配

5.4.5 过滤匹配

就像 SQL 一样, Neo4j 中提供 WHERE 子句来过滤 MATCH 的查询结果。

1
2
// 查询 `郭靖` 在哪些作品中出现
MATCH (n:作品)-[]-(m:角色) where m.name='郭靖' return n.name

Cypher过滤匹配

同时 WHERE 可以结合函数 exists() ,字符串匹配 starts with,ends with,contains,逻辑匹配 in,not,and,or 和正则表达式匹配进行更加精细的匹配。LIMIT 子句用于限制返回匹配结果的数量。

1
2
3
4
5
6
7
8
// 属性存在性检查函数 exists(),匹配所有拥有 desc 属性的节点
match (n) where exists(n.desc) return n
// 匹配所有 name 起始为 郭 的节点
match (n) where n.name starts with "郭" return n
// 匹配所有 与 郭靖 和 小龙女 有关的节点,同时过滤掉 郭啸天 和 张三丰
match p=(n)--(m) where n.name in ['郭靖','小龙女'] and not m.name in ['郭啸天','张三丰'] return p
// 匹配所有 name 包含 雕 的节点,这个正则表达式等价为 match(n) where n.name contains '雕' return n
match (n) where n.name =~ '.+?雕.+' return n

5.4.6 路径长度匹配

在关系中,允许匹配特定路径长度的内容,如:

1
2
3
4
5
(n)-[*2]->(m) 表示关系数量为 2 的 3 个节点的匹配, 等价于 (a)-[]->()-[]->(b)
(n)-[*2..4]->(m) 匹配路径长度为 2 到 4 之间的路径
(n)-[*2..]->(m) 匹配路径长度大于 2 的路径
(n)-[*..4]->(m) 匹配路径长度小于 4 的路径
(n)-[*]->(m) 匹配任意长度的路径

路径长度匹配示例如下:

1
2
// 匹配 郭啸天 到 黄蓉,路径长度为 1 到 2 的所有结果
MATCH p=(n)-[*1..2]-(m) where n.name='郭啸天' and m.name='黄蓉' return p

Cypher路径长度匹配

5.4.7 SHORTESTPATH 函数

shortestPath 函数用于查找两个节点之间的最短路径。 如查找 郭啸天黄蓉 之间的关系。

1
MATCH p=shortestPath((n:角色 {name:"郭啸天"})-[*]-(m:角色 {name:"黄蓉"})) return p

Cypher查找节点最短路径

6. 使用Neovis.js将Neo4j前端可视化

项目简介:Neovis.js将JavaScript可视化和Neo4j无缝集成。与Neo4j的连接非常简单明了,并且由于它是在Neo4j的属性图模型的基础上构建的,因此 Neovis 的数据格式与数据库保持一致。在单个配置对象中定义基于标签、属性、节点和关系的自定义和着色样式。

项目地址:https://github.com/neo4j-contrib/neovis.js/

neovis.js效果

7. 参考资料

[1] docker安装部署neo4j from 打瞌睡的布偶猫

[2] Neo4j 和 Mysql 查询基本语法的区别 from CodingDiary

[3] 图数据库-Neo4j(二):Cypher语法 from CSDN

[4] neo4j的概述和Cypher命令介绍 from 稀土掘金

[5] Neo4j Cypher 查询语法 from 知乎

[6] Cypher 语法(一)from CSDN

[7] Neo4j 数据导入 from 知乎

[8] 知识图谱 构建射雕三部曲人物关系 from CSDN

[9] 知识图谱 Linux安装Neo4j图数据库 from CSDN

[10] 知识图谱 neo4j.conf 配置文件解读说明 from CSDN

[11] 知识图谱 Neo4j基本操作及数据库文件导入 from CSDN

[12] 知识图谱 Neo4j Cypher查询语言详解 from CSDN

[13] 知识图谱 Python.py2neo操作Neo4j from CSDN

[14] 知识图谱 构建《射雕三部曲》图谱(CSV文件) from CSDN

[15] 知识图谱 深度学习:Keras 初探 from CSDN

[16] 知识图谱 命名实体识别(NLP) from CSDN

[17] 知识图谱 关系抽取与总结展望 from CSDN

[18] 在docker 容器中 neo4j数据的导入导出 from 代码先锋网

[19] Neo4j导入数据的5种方式详解配图 from CSDN

[20] Python操作Neo4j数据库,知识图谱,根据相似度计算的电影推荐的Demo from Github

[21] SPRINGBOOT整合NEO4J from 是小张啊

[22] springboot整合neo4j from CSDN

[23] Spring Boot 整合 SpringDataNeo4j 并封装工具类解析 PathValue from 爱代码爱编程

[24] SpringBoot集成Neo4j图数据库,利用Spark的朴素贝叶斯分类器实现基于电影知识图谱的智能问答系统 from Github

[25] 史上最全—Neo4j 前端可视化组件及相关资源 from 知乎

[26] Neo4j+springboot+vue+d3.js知识图谱构建和可视化 from Github

[27] 带有 Spring Data Neo4j 的 Neo4j 电影示例 from Github