知识存储概述
知识图谱以图结构来对知识进行建模和表示,所以常将知识图谱中的知识作为图数据进行存储。图数据库管理系统和RDF存储系统使用图数据模型。
图数据库
图数据库(Graph database)指的是以图数据结构的形式来存储和查询数据的数据库。
属性图(property graph)是图数据库领域中采用最广的 一种数据类型
- 由节点和边构成
- 节点可以用一个或者多个标签(labels)
- 节点可以有属性
- 边有一个类型(type)和方向
- 边也可以有属性
Neo4J
最流行的图数据库
图数据库查询语言:Cypher
声明式语言,用户只需声明“查什么”,无需关心怎么查。其特点和sql有很多相似的地方。match、where、return是最常用到的关键词:
- match: 相当于 sql中的select,用来说明查询匹配的数据模式(或者说图模式)
- where: 用来限制node或者关系中部分属性的属性值,从而返回我们想要的数据
- return: 返回节点或者关系
此外还有两个关键词:create和merge
- merge:在数据库中可以匹配到模式相同的数据就返回,没有则创建一条这样的数据(有则返回,没有则创建)
- create: 无论如何,都会创建一条新的数据
创建
1.
首先,我们删除数据库中以往的图,确保一个空白的环境进行操作
MATCH (n) DETACH DELETE n
这里,MATCH是匹配操作,而小括号()代表一个节点node(可理解为括号类似一个圆形),括号里面的n为标识符。
2.
接着,我们创建一个人物节点:
create (n:人类{name:'韦旭贤'}) return n
CREATE是创建操作,"人类"是标签,代表节点的类型。花括号{}代表节点的属性,属性类似Python的字典。这条语句的含义就是创建一个标签为"人类"的节点,该节点具有一个name属性,属性值是"韦旭贤"。
如下为成功创建的结点

3.
我们继续来创建更多的人物节点,并分别命名:
create (n:人类{name:'李绍健'}) return n;
create (n:人类{name:'李捷'}) return n;
create (n:人类{name:'张雨凡'}) return n;
create (n:人类{name:'黄哲涵'}) return n;

4.
接下来创建地区节点
CREATE (n:地区 {city:'上海', country:'中国'});
CREATE (n:地区 {city:'北京', country:'中国'});
CREATE (n:地区 {city:'重庆', country:'中国'});
CREATE (n:地区 {city:'成都', country:'中国'});
CREATE (n:地区 {city:'洛杉矶', country:'美国'});
可以看到,节点类型为Location,属性包括city和country。

5.
match (a:`人类`{name:'韦旭贤'}),(b:`人类`{name:'李绍健'}) merge (a)-[:couple]->(b)
这里的方括号[]即为关系,couple为关系的类型。注意这里的箭头-->是有方向的,表示是从a到b的关系。 如图,韦旭贤和李绍健之间建立了couple关系,通过Neo4J的可视化很明显的可以看出:

6.
关系也可以增加属性
match (a:`人类`{name:'韦旭贤'}),(b:`人类`{name:'李绍健'}) merge (a)-[:couple{since:2000}]->(b)

在关系中,同样的使用花括号{}来增加关系的属性,也是类似Python的字典,这里给couple关系增加了since属性,属性值为2000,表示他们建立CP关系的时间。
7.
接下来增加更多的关系,增加完如下
match (a:`人类`{name:'李绍健'}),(b:`人类`{name:'李捷'}) merge (a)-[:son{since:2001}]->(b);
match (a:`人类`{name:'李绍健'}),(b:`人类`{name:'黄哲涵'}) merge (a)-[:friend{since:2000}]->(b);
......

8.
然后,我们需要建立不同类型节点之间的关系-人物和地点的关系
MATCH (a:人类 {name:'张雨凡'}), (b:地区 {city:'重庆'}) MERGE (a)-[:BORN_IN {year:2000}]->(b);
MATCH (a:人类 {name:'李绍健'}), (b:地区 {city:'上海'}) MERGE (a)-[:BORN_IN {year:2000}]->(b);
MATCH (a:人类 {name:'李捷'}), (b:地区 {city:'北京'}) MERGE (a)-[:BORN_IN {year:2000}]->(b);
MATCH (a:人类 {name:'黄哲涵'}), (b:地区 {city:'成都'}) MERGE (a)-[:BORN_IN {year:2000}]->(b);

查询
1.
查询所有对外有关系的节点,以及关系类型
MATCH (a)-[r]->() RETURN a.name, type(r)

2.
查询所有有couple关系的节点
MATCH (n)-[:couple]-() RETURN n

3.
创建节点的时候就建好关系
CREATE (a:人类 {name:'李道丰'})-[r:teacher]->(b:人类 {name:'刘林'})

4.
连续查找
MATCH (a:人类 {name:'韦旭贤'})-[r1:couple]-()-[r2:son]-(couple_son) RETURN couple_son.name AS father

5.
增加/修改节点的属性
MATCH (a:人类 {name:'韦旭贤'}) SET a.age=20

这里,SET表示修改操作
6.
删除节点的属性

删除属性操作主要通过REMOVE
7.
删除结点
MATCH (a:地区 {city:''}) DELETE a
删除节点操作是DELETE
Comments | NOTHING