[知识图谱构建] 二.《Neo4j基础入门》基础学习之建立图数据库节点及关系

该系列文章主要讲解知识图谱及Neo4j图数据库的用法,本篇文章是做者学习《Neo4j基础入门》书籍的在线笔记,主要讲解Neo4j的基础知识及基本语法,但愿你们喜欢。
前文:
[知识图谱构建] 一.Neo4j图数据库安装初识及药材供应图谱实例
neo4j 实战、实例、示例 建立电影关系图 -1
https://www.w3cschool.cn/neo4j/node

PS:2019年1~2月做者参加了CSDN2018年博客评选,但愿您能投出宝贵的一票。我是59号,Eastmount,杨秀璋。投票地址:https://bss.csdn.net/m/topic/blog_star2018/indexweb

五年来写了314篇博客,12个专栏,是真的热爱分享,热爱CSDN这个平台,也想帮助更多的人,专栏包括Python、数据挖掘、网络爬虫、图像处理、C#、Android等。如今也当了两年老师,更是以为有义务教好每个学生,让贵州学子好好写点代码,学点技术,"师者,传到授业解惑也",提早祝你们新年快乐。2019咱们携手共进,为爱而生。

一.基础知识

1.节点(Node)
节点是图数据库的基本元素,表示一个实体记录,至关于关系数据库中的一条记录。在Neo4j中节点能够包括多个属性(Property)和多个标签(Label)。下图中节点包括两个属性,id和name。sql

match(n{name:"格尔木源鑫堂"}) return n

2.关系(Relationship)
关系是图数据库中的基本元素,当数据库中存在节点后,须要将节点链接起来构成图。关系用来链接两个节点,也称为图论的边(Edge),起始端和结束端都必须是节点,关系不能从空发起,关系能够包含多个属性。数据库

match(n) return n

3.属性(Property)
节点和关系均可以有多个属性。属性是由键值对组成的 <属性:属性值>。属性值能够是基本的数据类型或基本数据类型组成的数组。好比:boolean、byte、short、int、char、double、float、long、string。数组

4.路径(Path)
当建立图后,图中任意两个节点之间都是可能存在路径的,它是由节点和关系组成的,路径是有长度的。单独一个节点能够组成路径长度为0,两个节点之间的路径长度为1,依次类推。网络

match(n:Enterprise{name:"威门药业"})-[:买入]->(herb) return n,herb

输出“威门药业”买入的药品路径,以下图所示:数据结构

5.遍历(Traversal)
节点能够被关系串联或并联起来,因为关系能够有方向的,因此可在图中进行遍历操做。图遍历时能够指定有方向或无方向,所以在建立关系时没必要为两个节点建立互相指向的关系,而是在遍历时不指定遍历方向便可。svg

遍历一张图就是按照必定的规则,根据它们之间的关系,依次访问全部相关联的节点的操做。Neo4j提供了遍历操做,包括广度优先和深度优先搜索,采用Cypher实现。学习


二.建立图数据库节点

(一) 基础

点击“Add Graph”建立项目 “Graph1219”,以下图所示。spa

点击“Start”按钮开始绘制图。

1.单标签节点建立语法
使用create关键字建立单个节点使用下面语句,其中表示节点名称,表示标签名称。

CREATE (<node-name>:<label-name>)

下面代码是建立一个节点为Book。

create(m:Book)
Added 1 label, created 1 node, completed after 140 ms.
match(n) return n

输出结果以下所示:

2.多标签节点建立语法
下面是使用create关键字建立一个节点多个标签的状况。

CREATE (<node-name>:<label-name1>:<label-name2>.....:<label-namen>)

实例以下:

create(m:Cinema:Film:Movie:Picture)
Added 4 labels, created 1 node, completed after 34 ms.
match(n) return n

输出结果如所示:

(二) 实例

接下来说解具体的实例,老师、学生、课程之间的关系。

1.使用Cypher语句建立学生节点
使用Cypher中create指令建立六个Student节点,这些节点包括姓名、性别、学院和出生日期四个属性。

create(stu1:Student{ name:'王建平', Sex:'男', Sdept:'自动化', Sbirth:'1996-01-12' })
create(stu2:Student{ name:'刘华', Sex:'女', Sdept:'自动化', Sbirth:'1995-07-01' })
create(stu3:Student{ name:'范林军', Sex:'女', Sdept:'计算机', Sbirth:'1994-06-30' })
create(stu4:Student{ name:'李伟', Sex:'男', Sdept:'数学', Sbirth:'1995-05-01' })
create(stu5:Student{ name:'黄艳', Sex:'女', Sdept:'数学', Sbirth:'1996-04-01' })
create(stu6:Student{ name:'何纯', Sex:'男', Sdept:'数学', Sbirth:'1995-06-30' })

执行 “match(n) return n” 显示结果以下图所示:

2.使用Cypher语句建立课程节点
使用Cypher中create指令建立五个Course节点,表示课程,这些节点包括姓名、课时和编号三个属性。

create(Course1:Course{ name:'英语', Ctime:'64', Cno:'C01'})
create(Course2:Course{ name:'数据结构', Ctime:'48', Cno:'C02'})
create(Course3:Course{ name:'Python', Ctime:'64', Cno:'C03'})
create(Course4:Course{ name:'计算机网络', Ctime:'32', Cno:'C04'})
create(Course5:Course{ name:'数据库', Ctime:'48', Cno:'C05'})

设置不一样类型节点的颜色,而后执行 “match(n) return n” 显示结果以下图所示:

3.使用Cypher语句建立教师节点
使用Cypher中create指令建立四个Teacher节点,表示教师,这些节点包括姓名、性别和学院三个属性。

create(Tea1:Teacher{ name:'杨秀璋', Sex:'男', Dept:'计算机'})
create(Tea2:Teacher{ name:'小民', Sex:'男', Dept:'计算机'})
create(Tea3:Teacher{ name:'小娜', Sex:'女', Dept:'英语'})
create(Tea4:Teacher{ name:'小王', Sex:'男', Dept:'计算机'})

设置不一样类型节点的颜色,而后执行 “match(n) return n” 显示结果以下图所示:

4.使用Cypher语句建立学院节点
使用Cypher中create指令建立四个Department节点,表示学院节点,这些节点包括姓名和编号两个属性。

create(Dept1:Department{ name:'自动化学院', No:'001'})
create(Dept2:Department{ name:'计算机学院', No:'002'})
create(Dept3:Department{ name:'英语学院', No:'003'})
create(Dept4:Department{ name:'数学学院', No:'004'})

显示结果以下图所示:


三.建立图数据库关系

接着建立学生、课程、教师和学院之间的关系,但遇到了一个问题。

问题:
在建立学生-课程之间选课关系过程当中,遇到了一个问题。

create 
(stu1)-[:选课]->(Course1), (stu1)-[:选课]->(Course2), (stu1)-[:选课]->(Course3),
(stu2)-[:选课]->(Course1), (stu2)-[:选课]->(Course2), (stu2)-[:选课]->(Course3),
(stu3)-[:选课]->(Course1), (stu3)-[:选课]->(Course2), (stu3)-[:选课]->(Course3), 
(stu3)-[:选课]->(Course4), (stu3)-[:选课]->(Course5),
(stu4)-[:选课]->(Course1), (stu4)-[:选课]->(Course3), (stu4)-[:选课]->(Course5),
(stu5)-[:选课]->(Course1), (stu5)-[:选课]->(Course3), (stu5)-[:选课]->(Course5),
(stu6)-[:选课]->(Course1), (stu6)-[:选课]->(Course3), (stu6)-[:选课]->(Course5)

运行结果以下图所示,它没有把节点关联起来,而是从新建立了一组节点及关系。而书中直接能建立对应的关系,很是疑惑。

而若是是使用下面这个语句,用match先找到两个节点,而后在给两个节点添加关系,但它并非在stu1和Course1之间建立了一条关系,而是全部学生和课程之间均建立了关系。

MATCH (stu1:Student),(Course1:Course)
create (stu1)-[:选课]->(Course1)

显示以下所示:

那怎么解决呢?
原来,在实际操做,在建立节点的同时建立关系,即建立节点和关系语句必须一次执行完,不然如上面所述,建立关系时括号()中的节点被认为是新的节点。

好比执行下面这段书中电影代码,Keanu等做为节点的标识符能够被下面识别,分开执行后面语句是认为新的节点。

CREATE (TheMatrix:Movie {title:'The Matrix', released:1999, tagline:'Welcome to the Real World'})
CREATE (Keanu:Person {name:'Keanu Reeves', born:1964})
CREATE (Carrie:Person {name:'Carrie-Anne Moss', born:1967})
CREATE (Laurence:Person {name:'Laurence Fishburne', born:1961})
CREATE (Hugo:Person {name:'Hugo Weaving', born:1960})
CREATE (LillyW:Person {name:'Lilly Wachowski', born:1967})
CREATE (LanaW:Person {name:'Lana Wachowski', born:1965})
CREATE (JoelS:Person {name:'Joel Silver', born:1952})
CREATE
  (Keanu)-[:ACTED_IN {roles:['Neo']}]->(TheMatrix),
  (Carrie)-[:ACTED_IN {roles:['Trinity']}]->(TheMatrix),
  (Laurence)-[:ACTED_IN {roles:['Morpheus']}]->(TheMatrix),
  (Hugo)-[:ACTED_IN {roles:['Agent Smith']}]->(TheMatrix),
  (LillyW)-[:DIRECTED]->(TheMatrix),
  (LanaW)-[:DIRECTED]->(TheMatrix),
  (JoelS)-[:PRODUCED]->(TheMatrix)

CREATE (Emil:Person {name:"Emil Eifrem", born:1978})
CREATE (Emil)-[:ACTED_IN {roles:["Emil"]}]->(TheMatrix)

而后执行 “match(n) return n” 显示结果以下图所示:

完美解决方法
1.首先须要把数据清空,重来插入节点数据。

删除关系
MATCH (n)-[r]-()
DELETE r

单纯删除因此节点:
match (n)
delete n

2.而后执行全部代码,包括插入节点及插入关系。关系包括:
(1) 建立学生-课程之间关系 选课
(2) 建立教师-课程之间关系 授课
(3) 建立学生-学院之间关系 属于
(4) 建立教师-学院之间关系 隶属

下面这段代码是建立学生和课程之间的关系,代码以下:

create(stu1:Student{ name:'王建平', Sex:'男', Sdept:'自动化', Sbirth:'1996-01-12' })
create(stu2:Student{ name:'刘华', Sex:'女', Sdept:'自动化', Sbirth:'1995-07-01' })
create(stu3:Student{ name:'范林军', Sex:'女', Sdept:'计算机', Sbirth:'1994-06-30' })
create(stu4:Student{ name:'李伟', Sex:'男', Sdept:'数学', Sbirth:'1995-05-01' })
create(stu5:Student{ name:'黄艳', Sex:'女', Sdept:'数学', Sbirth:'1996-04-01' })
create(stu6:Student{ name:'何纯', Sex:'男', Sdept:'数学', Sbirth:'1995-06-30' })
create(Course1:Course{ name:'英语', Ctime:'64', Cno:'C01'})
create(Course2:Course{ name:'数据结构', Ctime:'48', Cno:'C02'})
create(Course3:Course{ name:'Python', Ctime:'64', Cno:'C03'})
create(Course4:Course{ name:'计算机网络', Ctime:'32', Cno:'C04'})
create(Course5:Course{ name:'数据库', Ctime:'48', Cno:'C05'})
create(Tea1:Teacher{ name:'杨秀璋', Sex:'男', Dept:'计算机'})
create(Tea2:Teacher{ name:'小民', Sex:'男', Dept:'计算机'})
create(Tea3:Teacher{ name:'小娜', Sex:'女', Dept:'英语'})
create(Tea4:Teacher{ name:'小王', Sex:'男', Dept:'计算机'})
create(Dept1:Department{ name:'自动化学院', No:'001'})
create(Dept2:Department{ name:'计算机学院', No:'002'})
create(Dept3:Department{ name:'英语学院', No:'003'})
create(Dept4:Department{ name:'数学学院', No:'004'})
create 
(stu1)-[:选课]->(Course1), (stu1)-[:选课]->(Course2), (stu1)-[:选课]->(Course3),
(stu2)-[:选课]->(Course1), (stu2)-[:选课]->(Course2), (stu2)-[:选课]->(Course3),
(stu3)-[:选课]->(Course1), (stu3)-[:选课]->(Course2), (stu3)-[:选课]->(Course3), 
(stu3)-[:选课]->(Course4), (stu3)-[:选课]->(Course5),
(stu4)-[:选课]->(Course1), (stu4)-[:选课]->(Course3), (stu4)-[:选课]->(Course5),
(stu5)-[:选课]->(Course1), (stu5)-[:选课]->(Course3), (stu5)-[:选课]->(Course5),
(stu6)-[:选课]->(Course1), (stu6)-[:选课]->(Course3), (stu6)-[:选课]->(Course5)

输出结果以下图所示,能够看到选修数据库(Course5)的学生包括何纯、李伟、黄艳和范林军。也能够看到学生何纯(stu6)选修了课程数据库(Course5)、Python(Course3)、英语(Course1)。

(stu6)-[:选课]->(Course1), (stu6)-[:选课]->(Course3), (stu6)-[:选课]->(Course5)

接着是最终的完整CQL语句,代码以下:

create(stu1:Student{ name:'王建平', Sex:'男', Sdept:'自动化', Sbirth:'1996-01-12' })
create(stu2:Student{ name:'刘华', Sex:'女', Sdept:'自动化', Sbirth:'1995-07-01' })
create(stu3:Student{ name:'范林军', Sex:'女', Sdept:'计算机', Sbirth:'1994-06-30' })
create(stu4:Student{ name:'李伟', Sex:'男', Sdept:'数学', Sbirth:'1995-05-01' })
create(stu5:Student{ name:'黄艳', Sex:'女', Sdept:'数学', Sbirth:'1996-04-01' })
create(stu6:Student{ name:'何纯', Sex:'男', Sdept:'数学', Sbirth:'1995-06-30' })
create(Course1:Course{ name:'英语', Ctime:'64', Cno:'C01'})
create(Course2:Course{ name:'数据结构', Ctime:'48', Cno:'C02'})
create(Course3:Course{ name:'Python', Ctime:'64', Cno:'C03'})
create(Course4:Course{ name:'计算机网络', Ctime:'32', Cno:'C04'})
create(Course5:Course{ name:'数据库', Ctime:'48', Cno:'C05'})
create(Tea1:Teacher{ name:'杨秀璋', Sex:'男', Dept:'计算机'})
create(Tea2:Teacher{ name:'小民', Sex:'男', Dept:'计算机'})
create(Tea3:Teacher{ name:'小娜', Sex:'女', Dept:'英语'})
create(Tea4:Teacher{ name:'小王', Sex:'男', Dept:'计算机'})
create(Dept1:Department{ name:'自动化学院', No:'001'})
create(Dept2:Department{ name:'计算机学院', No:'002'})
create(Dept3:Department{ name:'英语学院', No:'003'})
create(Dept4:Department{ name:'数学学院', No:'004'})
create 
(stu1)-[:选课]->(Course1), (stu1)-[:选课]->(Course2), (stu1)-[:选课]->(Course3),
(stu2)-[:选课]->(Course1), (stu2)-[:选课]->(Course2), (stu2)-[:选课]->(Course3),
(stu3)-[:选课]->(Course1), (stu3)-[:选课]->(Course2), (stu3)-[:选课]->(Course3), 
(stu3)-[:选课]->(Course4), (stu3)-[:选课]->(Course5),
(stu4)-[:选课]->(Course1), (stu4)-[:选课]->(Course3), (stu4)-[:选课]->(Course5),
(stu5)-[:选课]->(Course1), (stu5)-[:选课]->(Course3), (stu5)-[:选课]->(Course5),
(stu6)-[:选课]->(Course1), (stu6)-[:选课]->(Course3), (stu6)-[:选课]->(Course5)
create
(Tea1)-[:教课]->(Course3),(Tea1)-[:教课]->(Course5),
(Tea2)-[:教课]->(Course2),
(Tea3)-[:教课]->(Course1),
(Tea4)-[:教课]->(Course4),(Tea4)-[:教课]->(Course5)
create
(Tea1)-[:隶属{rela:'普通教师'}]->(Dept2),
(Tea2)-[:隶属{rela:'副院长'}]->(Dept2),
(Tea3)-[:隶属{rela:'副院长'}]->(Dept3),
(Tea4)-[:隶属{rela:'系主任'}]->(Dept1)
create
(stu1)-[:包括]->(Dept1),
(stu2)-[:包括]->(Dept1),
(stu3)-[:包括]->(Dept2),
(stu4)-[:包括]->(Dept4),
(stu5)-[:包括]->(Dept4),
(stu6)-[:包括]->(Dept4);

关系:
(1)学生-课程
选课:王建平选择课程一、二、3,刘华选择课程一、二、3,范林军选择课程一、二、三、四、5,李伟、黄艳、何纯同属于数学学院,选课为一、三、5。
(2)教师-课程
授课:杨秀璋教数据库、Python,小民教数据结构,小娜教英语,小王教数据库和计算机网络。
(3)教师-学院
隶属:杨秀璋隶属于计算机学院(属性:普通教师),小民隶属于计算机学院(属性:副院长),小娜隶属于英语学院(属性:副院长),小王隶属于自动化学院(属性:系主任)。
(4)学生-学院
包括:自动化学院包括学生王建平、刘华,计算机学院包括学生范林军,数学学院包括李伟、黄艳、何纯。

最终输出的关系以下图所示:

写到这里这篇文章基本结束,我后续将继续深刻学习找到更好地解决方法,MATCH中增长WHERE应该能够定位指定节点,实现定向的关系补充或修改。同时,若是数据量多我也建议使用CSV文件导入。总之,但愿基础文章对您有所帮助,一块儿加油。

(By: Eastmount 2018-12-19 晚7点 https://blog.csdn.net/Eastmount/ )