一. 前言
本文主要使用Neo4j中常见的CQL语句实现一个简单的案例,是十分基础的。
作者的能力十分有限,若有文章有误,欢迎指正。若您有任何想法,欢迎交流。
二. Neo4j介绍
1. 什么是Neo4j
Neo4j是一个开源的NoSQL图形数据库,2003 年开始开发,使用 scala和java 语言,2007年开始发布。
是世界上最先进的图数据库之一,提供原生的图数据存储,检索和处理;
采用属性图模型(Property graph model),极大的完善和丰富图数据模型;
专属查询语言 Cypher,直观,高效;
官网:https://neo4j.com/
2.Neo4j数据模型
Neo4j作为图数据库,数据模型肯定有别于常见的关系型数据库。
图数据库数据模型的主要构建块是:节点、关系、属性。
以下是一个简单的属性图例子:
不难看出,圆圈代表各个节点,各节点之间用有方向的箭头表示关系。
三. CQL语句
CQL代表Cypher查询语言,在Neo4j中,我们使用CQL语句对数据库进行操作。
以下是一些常用的CQL命令:
是不是与SQL语句有些类似?接下来,我们通过构建小猪佩奇的家庭关系图,学习简单的CQL语句。
1.创建
我们知道,小猪佩奇一家主要有猪爸爸、猪妈妈、佩奇、乔治。
我们在Neo4j中该如何表示呢,我们可以通过创建四个节点来表示他们。
我们通过如下的语句先来创建一个猪爸爸的节点。
create (:pig{name:'猪爸爸',age:10})
在此语句中,creat()
创建了一个节点,括号内:
后面的pig为节点标签名称。{}
内的键值对,表示该节点所拥有的属性。
我们也可以创建多个节点,各节点之间使用,
隔开:
create(:pig{name:"佩奇", age:5}),(:pig{name:"乔治", age:3});
此外,还可以在创建节点的同时创建关系。
--- 注意:这里会创建两个节点(猪爸爸和猪妈妈)
create(:pig{name:'猪妈妈',age:9})-[:夫妻{age:5}]->(:pig{name:"猪爸爸",age:10});
需要注意的是,关系是有方向的,
使用(节点a) - [关系] -> (节点b)
来表示,其中关系也可以有属性(这里为夫妻的婚龄)
创建关系的内容在后面也会讲解。
至此,我们创建好了如下关系:
2.查询
假如我们想要查询某一个成员的信息,我们该如何查询呢?
我们可以使用match()
语句来查询,以查询佩奇的信息为例,使用如下语句:
match(p:pig{name:'佩奇'}) return p
这样就可以查询到佩奇的相关信息,如下图
需要注意的是,在match()
之后,需要使用return()
进行返回。
这里的p
可以任意,有点类似于函数中的形式参数。
刚才我们说到,可以在创建节点的时候可以连同关系一起创建,假如我们想给已有的关系创建节点,我们应该如何操作?
我们可以先查询出需要创建关系的节点,然后创建关系,如下方语句所示:
match (a:pig{name:'猪爸爸'}) match (b:pig{name:'乔治'}) create (a)-[p:父子]->(b)
--- 也可以将第二个match替换为逗号,查询多个节点
我们将其余的关系补全:
--- 创建姐弟关系
match (a:pig{name:'佩奇'}) match (b:pig{name:'乔治'}) create (a)-[p:姐弟]->(b)
--- 创建猪妈妈与佩奇、乔治的关系
match (a:pig{name:'猪妈妈'}) match (b:pig{name:'佩奇'}) create (a)-[p:母女]->(b)
match (a:pig{name:'猪妈妈'}) match (b:pig{name:'乔治'}) create (a)-[p:母子]->(b)
--- 创建猪爸爸与佩奇的关系
match (a:pig{name:'猪爸爸'}) match (b:pig{name:'佩奇'}) create (a)-[p:父女]->(b)
如果我们想单独查询某两个成员之间的关系,我们可以使用match (节点a) - [关系] -> (节点b) return a,b
的方法来查询并返回:
match (a:pig{name:'佩奇'}) - [:姐弟] -> (b:pig{name:'乔治'}) return a,b
查询到的结果如下:
假如我们想查询所有家庭成员以及成员之间的关系,即整个家庭关系图,我们可以使用如下语句:
MATCH (n:pig) RETURN n
这里查询了所有标签为pig
的节点并返回。
在语句的最后也可以使用LIMIT
子句或SKIP
来过滤或限制查询返回的行数( 简单理解为:LIMIT
返回前几行,SKIP
忽略前几行。)
而这里的条数较少,效果不明显,仅为对LIMIT
和SKIP
的补充解释。
3.修改
假如佩奇长大了一岁,我们该如何修改佩奇的年龄呢?
我们可以先将佩奇的信息查询出来,接着再修改年龄,语句如下:
佩奇原先的年龄为5岁,我们将其修改为6岁。
match(a:pig{name:'佩奇'}) set a.age=6 return a
并将佩奇的节点返回,查看修改后的属性。
可以看到age
已被修改为6岁,修改成功。
我们也可以结合where
子句来使用,如将pig
标签中年龄为10的节点的年龄修改为11岁,并将节点返回,语句如下:
match (a:pig) where a.age=10 set a.age=11 return a
如此一来,原先年龄为10的节点(猪爸爸)的年龄就被更改为了11岁。
此外,也可以根据id来修改信息,在Neo4j中,节点自带一个<id>
属性,而在where
子句中,也可以通过使用id()
函数来查询相应节点并进行操作,以下是一个通过id来修改年龄的例子:
match (a:pig) where id(a)=5 set a.age=4 return a
通过此语句,将id
为5的节点(即乔治)的年龄更改为了4。
需要注意,where
子句中的id()
为函数,所以才能使用id(a)
的形式。
关系的属性也可以修改,如我们可以修改猪妈妈与猪爸爸的婚龄:
match(a:pig{name:"猪妈妈"})-[r:夫妻]->(b:pig{name:"猪爸爸"}) set r.age=6;
如下图,夫妻关系中的婚龄属性已被修改。
4.删除
假设家庭成员中存在猪爷爷(节点已经提前被添加好,但并未删除),现在猪爷爷去世,我们需要将其删除。
我们可以使用以下语句对猪爷爷的节点进行删除:
match(a:pig{name:'猪爷爷'}) delete a;
但需要注意的是,该语句只适用于与其他节点没有关系的情况,如果存在关系,则无法删除,如下图所示:
所以我们在删除节点前,需要先删除与该节点有关的关系。
先删除关系:
match (a:pig{name:'猪爷爷'})-[p:父子]-(b:pig{name:'猪爸爸'}) delete p;
再删除节点:
match(a:pig{name:'猪爷爷'}) delete a;
我们也可以针对标签,对节点进行删除,使用以下语句:
match(a:pig) delete a
同样地,删除节点前也需要先删除关系。
假如我们需要清空数据库中的所有内容,我们可以使用如下语句:
MATCH (n) DETACH DELETE n
该语句能够快速清空数据库,且无需先删除关系。
除了使用delete
进行删除关系和节点以外,还可以使用remove
删除标签和属性。
可以使用以下语句删除节点的属性,以删除乔治的age
属性为例:
match(p:pig{name:'乔治'}) remove p.age
可以看到,乔治的age
属性已被删除。
同样可以使用以下语句删除节点的标签,以删除乔治的pig
标签为例:
match(p:pig{name:'乔治'}) remove p:pig
四. 最后
至此,Neo4j与CQL语句的基本介绍已经结束。
希望本文对您有用!