Neo4j之CQL基础

Neo4j之CQL基础

一、CQL概念

关系型数据库的查询语言是SQL,Neo4j 图数据库也有自己的查询语言,那就是CQL。

CQL全称Cypher Query Language,它是一种声明性的模式匹配语言,跟SQL非常类似,也遵循SQL的语法。

CQL的语句书写起来都非常简单,而且很人性化,可读性强。

二、CQL简介

如果熟悉SQL,那么CQL的语法很容易就学会了。 下面通过表格列出 CQL 中常用的一些命令和函数。

第一个是CQL常用命令

命令/释义用途
create/创建创建节点、关系或属性
match/匹配获取有关节点、关系或属性的数据
return/返回返回最终需要的查询结果
where/条件根据条件过滤数据
delete/删除删除节点、关系
remove/移除删除节点和关系的属性、标签
order by/排序对最终结果进行排序
set/组添加或者更新标签、属性

第二个是CQL常用函数

函数/释义用途
Aggregation/聚合对查询结果执行一些聚合操作
Relationship/关系获取关系的细节,如startnode,endnode等
String/字符串使用字符串的功能,例如截取子串、替换等

三、CQL命令使用

create

create命令可以用于创建节点,有两种语法,分别对应创建无属性的节点和有属性的节点。

//无属性
create (<node-name>:<label-name>)

//有属性
create (
   <node-name>:<label-name>
   { 	
      <Property1-name>:<Property1-Value>
      ........
      <PropertyN-name>:<PropertyN-Value>
   }
)

node-name是要创建的节点的具体名称,label-name是节点所属的标签的名称。即,一个标签要管理一组节点。
property-name和property-value是键值对,定义该节点的一个属性,即该属性的名称和值。

这里有个重要的点,那就是使用create命令一定会创建节点。当创建节点时,节点内部都会自带一个ID属性,该ID的值由系统内部给一个数字,然后自动递增。所以,就算定义两个节点的属性值全部相同,但是其内部ID值一定不同,系统会将他们视为两个独立节点。

示例如下:

//在数据库中创建了两个节点zhangsan和lisi,他们都属于标签Student。
create (zhangsan:Student)
create (lisi:Student)

//创建了一个节点xiaoming,也属于标签Student,有三个属性:id、name。dept
create (
    xiaoming:Student
    {
    	id: 001,
    	age:20,
    	dept:"CS"
    }
)

create也可以创建一个节点对应多个标签,语法为:

create (<node-name>:<label-name1>:<label-name2>.....:<label-nameN>)

示例:

create (xiaobai:Boy:Student:Person)
//这里xiaobai是节点名,Boy、Student、Person是该节点的多个标签名称

create还可以用于创建节点之间的关系,语法为:

create (<node1-name>:<label1-name>)-
	[<relationship-name>:<relationship-label-name>]
	->(<node2-name>:<label2-name>)

relationship-name是要创建的关系的具体名称,relationship-label-name是关系的标签名称。

具体示例如下,创建了两个节点,并且从节点b1到g1有一个单向的关系

create (b1:Boy)-[r1:Likes]->(g1:Girl)

注意,Neo4j中两个节点之间的关系是有方向性的,使用了箭头进行标记:() - []→()。如果没有使用箭头标记关系的方向:() - [] - (),那么Neo4j服务器会报错。

match+return

match命令语法为:

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

这里有个很重要的注意事项,不能单独使用match语句,必须和其他语句进行配合。如果单独使用match,系统将报错InvalidSyntax,我们使用时match经常与return配合。

return命令语法为:

return
	<node-name>.<property1-name>,
	······
	<node-name>.<propertyN-name>

return语句也是不能单独使用的,应该与match或者create语句配合

match配合return语句示例:

//检索Student标签下xiaoming节点的某几个属性
match (xiaoming:Student)
return xiaoming.id, xiaoming.age

//检索Student标签下xiaoming节点的所有属性
match (xiaoming:Student)
return xiaoming

where

where命令的用法和SQL完全一样,就是通过限制条件来过滤数据

//简单where
where <condition>
//复杂where
where <condition> <boolean-operator> <condition>

condition就是筛选条件,包括小于、大于、小于等于、大于等于、等于、不等于六种选择,例如 id>100,age<=20 等。值得注意的是,不等于用 <> 来进行表示。

boolean-operator就是布尔运算符,包括 AND、OR、NOT、XOR 四种,分别对应异或四种操作。

示例如下,假设现在数据库中有2个年龄20岁和2个年龄21岁的学生(标签Student),名字分别是zhangsan、lisi、zhangsan、lisi。

//查询年龄为21的学生
match (stu:Student)
where stu.age=21
return stu

//查询年龄为20且名字为zhangsan的学生
match (stu:student)
whhere stu.age=20 and stu.name="zhangsan"
return stu

delete

delete的删除方式有两种,一种是直接删除节点,但是要求删除的节点不能与其他节点有关系连接;另一种是将节点和关系一起删除。

//删除节点
delete <node-namelist>
//删除节点及其关系
delete <node1-name>,<node2-name>,<relationship-name>

示例如下,这里删除的都是之前create的节点

//删除节点
match (zhangsan:Student) delete zhangsan
//删除节点及其关系
match (b1:Boy)-[r1]-(g1:Girl)
delete b1,g1,r1

remove

delete与remove的相同点:

  • 两者都不能单独使用
  • 两者都应该和match命令配合使用

delete和remove的不同点:

  • delete用于删除节点和关系
  • remove用于删除标签和属性

remove语法:

//删除节点或关系的属性
remove <property-name-list>
//删除节点或关系的标签
remove <label-name-list>

示例如下:

//先创建节点
create (stu1:Student {sid:003,name:"xiao bai",age:19,dept:"SE"})
create (xiaohong:Girl:Student:Person)

//删除“dept”属性
match (stu1{sid:003})
remove stu1.dept
return stu1

//删除student、person标签
match (xiaohong:Girl)
remove xiaohong:Student,xiaohong:Person

set

set语法:

//添加/更新属性
set <property-name-list>

示例如下:

//先创建节点
create (stu2:Student {sid:004,name:"xiao gang",age:20,dept:"SE"})

//添加属性class
match (stu2:Student)
where stu2.dept="SE"
set stu2.class = "SE01"
return stu2

//已经存在属性class,则会将其更改为SE02
match (stu2:Student)
where stu2.dept="SE"
set stu2.class = "SE02"
return stu2

order by

order by命令可以对match查询的结果进行排序,默认是升序排序。语法如下:

在语句最后使用 limit n 可以仅获取结果的前n个节点

//升序
ORDER BY  <property-name-list>
//降序使用关键字 desc
ORDER BY  <property-name-list> desc

示例如下,假设数据库中存在5本书(标签Book),id分别为001至005,price分别是20、40、30、50、10

//按价格升序,获取前三个节点
match (book:Book)
return book
order by book.price 
limit 3

//按id降序
match (book:Book)
return book
order by book.id desc

merge

我们知道,create命令一定会创建节点,因此当我们想判断某个节点是否存在时,需要先使用match进行查询;如果存在就不用重复创建,如果不存在再使用create命令创建。

对于这种情况我们可以使用merge命令,merge命令其实就是create命令和match命令的结合。

merge命令的语法和create命令一模一样。但是merge的作用是,如果当前查询节点的属性存在,则不创建新的节点,如果属性不存在就创建新节点。

//创建新节点
merge (t1:Test{id:001, name:"hhh"})

//查询到属性值存在,不会创建节点
merge (t2:Test{name:"hhh"})
merge (t2:Test{id:001})

//查询到属性值不同,创建新节点
merge (t3:Test{id:002,name:"hhh"})
merge (t4:Test{id:003,name:"go"})

四、CQL函数使用

String

字符串常用函数一共是四个

函数效果
upper将字符串中的所有字母更改为大写字母
lower将字符串中的所有字母更改为小写字母
substring获取所给字符串的指定子字符串
replace替换所给字符串的子字符串

函数语法如下:

  • 一个字符串长度为n,索引值的区间是 0 到 n-1。
  • input-string是节点或关系的属性名称
  • startIndex是开始位置的索引值,endIndex是结尾位置的索引值,取值区间左闭右开。endIndex可以省略,省略时默认到字符串的结尾
  • StartString是要替换之前的子字符串,endString是要替换的字符串
upper (<input-String>)
lower (<input-string>)
substring (<input-string>,<startIndex> ,<endIndex>)
replace (<input-string>,<startString> ,<endString>)

示例如下:

create (
    b:Book
    {
    	name:"WildGrass",
    	price:30
    }
)

//结果为 WILDGRASS、wildgrass、wild、HomeGrass
match (b:Book)
return upper(b.name),lower(b.name),substring(b.name,0,4),replace(b.name,"Wild","Home")

这里需要注意,b.name的值一直是“WildGrass”。因为字符串函数用在return里面都作用于查询的数据,不会更改数据库中节点属性原本的值。

Aggregation

聚合函数的用法和SQL中完全一致

函数效果
count统计match命令返回的行数
max找到match命令返回的一组行中的最大值
min找到match命令返回的一组行中的最小值
sum统计match命令返回的一组行的值求和
avg统计match命令返回的一组行的值求平均值

函数语法如下:

count(<value>)		//<value>可以是*,节点或关系标签名称或属性名称
max(<property-name>)
min(<property-name>)
sum(<property-name>)
avg(<property-name>)

示例如下,假设数据库中存在5本书(标签Book),id分别为001至005,price分别是20、40、30、50、10

//结果为5
match (book:Book) return count(*)

//结果为50、10、150、50
match (book:Book) 
return max(book.price),min(book.price),sum(book.price),avg(book.price)

Relationship

CQL的关系函数可以在获取开始节点,结束节点等细节时知道该关系的细节。

函数效果
startnode获取关系的开始节点
endnode获取关系的结束节点
id获取关系的ID
type获取关系的类型信息

这里的 id 就是我们在create命令中提到的内部ID。

函数语法如下:

  • relationship-label-name是来自节点或关系的属性名称
  • relationship-name是关系名称
startnode (<relationship-label-name>)
endnode (<relationship-label-name>)
id (<relationship-name>)
type (<relationship-name>)

示例如下:

//先创建关系
create (b101:Boy)-[r101:Likes]->(g101:Girl)
create (s201:Student)-[r201:Read]->(b201:Book)

//获取指定关系的开始和结束节点
match (b)-[r:Likes]->(g)
return startnode(r),endnode(r)
//获取指定关系的id和type
match (s)-[r:Read]->(b)
return id(r),type(r)

//如果不指定关系,那么将会把所有类型的关系都查询出来
match (b)-[r]->(g)
return id(r),type(r)
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值