知识存储概述

知识图谱以图结构来对知识进行建模和表示,所以常将知识图谱中的知识作为图数据进行存储。图数据库管理系统和RDF存储系统使用图数据模型

图数据库

图数据库(Graph database)指的是以图数据结构的形式来存储和查询数据的数据库。

属性图(property graph)是图数据库领域中采用最广的 一种数据类型

  • 由节点和边构成
  • 节点可以用一个或者多个标签(labels)
  • 节点可以有属性
  • 边有一个类型(type)和方向
  • 边也可以有属性

Neo4J

最流行的图数据库

图数据库查询语言:Cypher

声明式语言,用户只需声明“查什么”,无需关心怎么查。其特点和sql有很多相似的地方。match、where、return是最常用到的关键词:

  • match: 相当于 sql中的select,用来说明查询匹配的数据模式(或者说图模式)
  • where: 用来限制node或者关系中部分属性的属性值,从而返回我们想要的数据
  • return: 返回节点或者关系

此外还有两个关键词:createmerge

  • 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