本文主要介绍Cypher 查询语言,并对知识图谱进行增删查改操作。
目录
1. 概述
Cypher 是图形数据库 Neo4j 的查询语言,就像SQL在关系型数据库中查询一样。Cypher 受到不同方法的启发,如 WHERE
和 ORDER BY
受到了 SQL 的启发,模式匹配则借用了 SPARQL 的表达式方法,一些列表语义借用了 Haskell 和 Python 等语言,Cypher 的构造基于英文散文和简洁的图像,使查询易于编写和阅读。客户端上方的输入栏用于输入 Cypher 语句,按回车或者点击右侧三角形按钮执行 Cypher 语句,shift + 回车 进行换行。
2. 数据类型
Cypher 中有以下几种基本类型
- 数值
- 字符串
- 布尔
- 节点
- 关系
- 列表
2.1数值,布尔,字符串
Cypher 中的数据类型如下
- boolean 用于表示布尔值:true false
- byte 用于表示 8 位整数
- short 用于表示 16 位整数
- int 用于表示 32 位整数
- long 用于表示 64 位整数
- float 用于表示 32 位浮点数
- double 用于表示 64 位浮点数
- char 用于表示 16 位字符
- string 用于表示字符串
数值类型支持的常用算术运算有
+
加法运算-
减法运算*
乘法运算/
除法运算%
取余运算^
幂运算
// 执行算术运算,用 return 返回结果,不同运算用,隔开
return 1+1,1.2-3,100000*1000,100/200,3%4,2^10,True,false
字符串类型支持的常用函数有
toUpper
用于将所有字母更改为大写字母toLower
用于将所有字母改为小写字母SUBSTRING
用于获取给定 String 的子字符串REPLACE
用于替换一个字符串的子字符串SPLIT
用于切分字符串+
用于字符串拼接
// 执行字符串函数,用 return 返回结果
return toUpper('a'),toLower('A'),SUBSTRING('abcdefghijk',1,3),replace('abcde','ab','de'),split('abc,def',','),'1'+'2'
2.2 节点和关系
Cypher 采用一对圆括号 ()
来表示节点,如 (n:角色)
表示一个 角色
节点,n
是变量名,供命令执行时用 n
来访问这个节点,在命令执行完毕后就无法使用了。同时单独的 ()
表示一个匿名节点,在匹配时表示匹配所有节点。
在关系中
-
--
表示无方向的关系 -
-->
表示有方向的关系 -
-[r]->
则给关系赋予一个变量名,方便对这个关系进行操作 -
-[r:配偶]->
匹配关系为配偶的类型
同时为了书写简单,可以为节点和关系语法赋予一个变量
//将所有 (角色)-[配偶]-() 的子图赋值给变量 p
p = (n:角色)-[r:配偶]-()
这样变量 p
就可以写到多个查询语句中,避免重复编写
2.3 列表
Cypher 支持列表操作,并且和 Python 中的列表很相似。通过 []
来创建列表,同时与 Python 相同,列表中可以包含不同的元素。
3. 语法
3.1 匹配语句
在 Neo4j
中,MATCH
命令用于从数据库中获取节点,关系的信息,类似于 SQL
中的 SELECT
。RETURN
则是在 MATCH
搜索完成后返回数据,因此 MATCH
必须与 RETURN
同时使用。
// 根据标签匹配节点
match (n:角色) return n // 匹配所有角色节点
// 根据标签和属性匹配节点
match (n:角色{name:'郭靖'}) return n // 匹配name为郭靖的角色节点
// 匹配任意关系
match p = (n)-[r]->(m) return p // 匹配出有任意关系的两个节点
optional match
类似于 match
,不同之处在于 optional match
在匹配不到内容时返回 null 方便查询继续进行,而 match
直接返回查询无结果。
// 用 optional match 匹配郭靖是否有关系到倚天屠龙记
optional match p=(n:角色{name:'郭靖'})-[r]->(:作品{name:'倚天屠龙记'}) return p
就像 SQL
一样, Neo4j
中提供 WHERE
子句来过滤 MATCH
的查询结果
// 查询郭靖在哪些作品中出现
MATCH (n:作品)-[]-(m:角色) where m.name='郭靖' return n.name
同时 WHERE
可以结合函数 exists()
,字符串匹配 starts with
,ends with
,contains
,逻辑匹配 in
,not
,and
,or
和正则表达式匹配进行更加精细的匹配
// 属性存在性检查函数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
// 在这里要注意到 not 是对整个结果取反,而不能写成 name not in
正则表达式的语法
// 匹配所有 name 包含 龙 的节点,这个正则表达式等价为 match(n) where n.name contains '龙' return n
match (n) where n.name =~ '.+?龙.+' return n
LIMIT
子句用于限制返回匹配结果的数量
// 查询射雕英雄传作品中三个角色名
MATCH (n:作品)-[]-(m:角色) where n.name='射雕英雄传' return m.name limit 3
在关系中,允许匹配特定路径长度的内容,如
(n)-[*2]->(m)
表示关系数量为 2 的 3 个节点的匹配,等价于(a)-[]->()-[]->(b)
(n)-[*2..4]->(m)
匹配路径长度为 2 到 4 之间的路径(n)-[*2..]->(m)
匹配路径长度大于 2 的路径(n)-[*..4]->(m)
匹配路径长度小于 4 的路径(n)-[*]->(m)
匹配任意长度的路径
// 匹配 郭靖 到 黄蓉,路径长度为 1 到 3 的所有结果
MATCH p=(n)-[*1..3]->(m) where n.name='郭靖' and m.name='黄蓉' return p
3.2 创建语句
在Neo4j
中,CREATE
命令用于创建节点和关系。
如创建一个金轮法王
节点,即在label
为角色的节点中创建一个name
为金轮法王
的节点,同时为这个节点拥有来自蒙古
的属性
// 创建角色节点,拥有属性name-金轮法王,from-蒙古
CREATE (n:角色 {name:'金轮法王',from:'蒙古'})
但在进行这个操作后,视图界面并不返回 Graph
界面,因为 CREATE
命令可以允许不跟 RETURN
同时使用,若使用了 RETURN
,才会返回 Graph
界面。
Neo4j 只支持有向图
,创建周伯通
与王重阳
的关系如下:
CREATE (n:角色{name:'王重阳',nickname:'中神通'})- [:师弟] ->(m:角色{name:'周伯通',nickname:'老顽童'})
3.3 混合使用
知识图中可以存在两个内容完全相同的节点,因此,要给已经存在的两个节点创建关系,则不能简单地使用 CREATE
命令,而是要先用 MATCH
找到已存在的节点,再构建关系。
如要创建金轮法王
与杨过
的关系,则先要找到金轮法王
和杨过
这两个节点,再向这两个节点之间添加关系。
match (n:角色),(m:角色) where n.name='金轮法王' and m.name='杨过' create (n)-[:对手]->(m)
3.4 MERGE命令
MERGE
命令是 CREATE
命令和 MATCH
命令的组合。 MERGE
在图中搜索给定模式,如果存在,则返回结果,如果不存在,则创建并返回结果
merge (n:门派{name:'少林'}) return n // 用MERGE命令增加少林门派
3.5 SET语句
SET
用于给现有节点或关系添加新属性,因此,SET
需要配合 MATCH
使用。 如给杨过节点增加一个 “西狂” 属性
match (n:角色) where n.name='杨过' set n.nickname='西狂' return n
3.6 SHORTESTPATH 函数
shortestPath
函数用于查找两个节点之间的最短路径。 如查找张无忌
与降龙十八掌
之间的关系
MATCH p=shortestPath(
(n:角色 {name:"张无忌"})-[*]-(m:武功 {name:"降龙十八掌"})
)
RETURN p
这个图说明,洪七公
曾经教授过 杨过
,杨过
又教授过 张三丰
,最后 张三丰
教授过 张无忌
,同时 洪七公
的武功有 降龙十八掌
。
3.7 删除语句
Neo4j 中有两种删除方法,DELETE
和 REMOVE
。DELETE
用于删除节点和关系,REMOVE
用于删除节点和关系的标签与属性。两者都需要配合 MATCH
,先匹配到内容,再执行操作。
1. 删除属性
用REMOVE将金轮法王的from属性删除。
match (n:角色) where n.name='金轮法王' remove n.from return n
2. 删除节点和边
若要删除节点,则需要删除与节点相关的所有边,这与图论一致——不存在没有节点的边。 因此要删掉金轮法王这个节点,就先需要找到该节点和所在关系,再进行删除
match (n:角色)-[r]-() where n.name='金轮法王' delete n,r
3. 清空数据库
要清空数据库,意味着要清空所有的节点和边,节点存在两种情况:有边连接的和孤立的节点,因此需要同时匹配这两种情况,再进行删除
match (n) optional match (n)-[r]-() delete n,r
3.8 FOREACH 函数
foreach 是 Cypher 中列表的更新工具,在 foreach 中,支持 create,merge,delete 和 foreach 对图进行修改。
// 从字符串文本中创建角色节点
foreach(name in split('郭靖,杨过,张无忌',',') | create(n:角色{name:name}))
4. 小结
本文介绍了 Cypher 的基本语法,并利用 Cypher 对射雕三部曲的知识图谱进行了简单的增删查改操作。
Cypher 基本命令总结如下表
命令 | 用法 |
---|---|
CREATE | 创建节点,关系和属性 |
MATCH | 检索有关节点,关系和属性 |
RETURN | 返回查询结果 |
WHERE | 提供条件过滤检索数据 |
DELETE | 删除节点和关系 |
REMOVE | 删除节点和关系的属性 |
SET | 添加或更新标签 |
Cypher 更具体的用法,可以参考官方文档。官方文档http://neo4j.com/developer/cypher/