鸟哥的Neo4j私房菜(二)

2017-09-18  本文已影响1006人  niaoge2016

还是写在前面?

按照原计划系列的第二篇博文来介绍一下Neo4j独特的查询语言——Cypher。这个在网上资料还是挺全的,鸟哥也没法把所有内容都覆盖,就挑选比较重要的内容介绍了,建议大家去官网查阅比较齐全的文档。

Cypher简介

Neo4j的查询语言称作Cypher,Cypher是对图形的声明查询语言,使用图形模式匹配作为主要的机制作图形数据选择(包括只读和变更操作)。

简单的查询语句
假如我们想要查询一个Job相邻的依赖Job,我们可以使用如下的查询语句

MATCH (n:Job) WHERE n.name="EXM" WITH n MATCH (:Job) - [:DEPEND] -> (b:Job) RETURN b

首先我们要指定起始节点,我们通过查找Job中name为"EXM"的节点来指定
下一步,设置需要输出结果的匹配模式。模式就是对需要检查数据库中的子图形的描述,它是由关系相互连接的一些节点构成。一个关系连接的两个节点是典型的图形模式,它是用
( )-[]-( )描述的。节点用圆括号( )指定,关系使用方括号[]指定。节点和关系使用连字符连接。(注意连字符可以包含方向!)
最后,要返回查询的结果,这里我们使用一个关键字RETURN来返回查询结果 b

Cypher的基本语法

Cypher句法由四个不同的部分组成, 每一部分都有一个特殊的规则:

Cypher的模式匹配性质使得图形模式成为任何查询的重点问题,因此我们重点介绍它。

MATCH模式匹配

① 使用节点和关系标识
在Cypher查询中,节点和关系都可以与标识关联,这种关联使得以后可以在同样的查询中引用同一个图形实体。
前面的例子中我们就给Job分别定义了别名n、b,当然关系也可以加上别名

MATCH (j:Job) - [d:DEPEND] -> (b:Job) RETURN b

如果没有给出别名,那么就是匿名节点/关系,后续如果不需要用到该节点/关系建议匿名,比如上面的例子的(:Job)和[:DEPEND]

② 复杂模式匹配
了解了简单的用法之后,我们来一个比较复杂一点的查询

MATCH (n:Job) WHERE n.name="EXM" WITH n 
MATCH p = (n) - [*] -> (m:Job) WHERE NOT m.description="EX" 
RETURN m

这个查询会返回指定名字为"EXM"的下游所有节点,然后过滤掉描述description值为"EX"的节点

看到这里,相信大家已经大概了解匹配模式的三大部分内容了,下面将对这三大部分进行更加详细地介绍。

start job = node(1)
RERUEN job

② 通过多个节点编号加载多个节点
在start语句中使用多个编号,需要列出以逗号隔开的编号参数值,如下所示:

start job = node(1,3)
MATCH job - [:DEPAND] -> (b:job)
RETURN b

③ 使用索引查找

start job = node:job(name = "EXM")
RETURN job

④ 使用基于模式的索引查找

MATCH (job:job)
WHERE job.name = "EXM"
RETURN job
MATCH (n:Job) WHERE n.name="EXM" WITH n 
MATCH (:Job) - [:DEPEND] -> (b:Job) 
WHERE b.email =~ /.*@gmail.com/
RETURN b

① 返回属性
上面的例子基本都是返回节点信息,我们也可以返回节点的属性信息

MATCH (n:Job) WHERE n.name="EXM" WITH n 
MATCH (:Job) - [:DEPEND] -> (b:Job) 
WHERE b.email =~ /.*@gmail.com/
RETURN b.name

② 返回关系
同样,我们也可以返回感兴趣的关系或者是关系的属性值

MATCH (n:Job) WHERE n.name="EXM" WITH n 
MATCH (:Job) - [d:DEPEND] -> (b:Job) 
WHERE b.email =~ /.*@gmail.com/
RETURN d

③ 返回路径
除节点和属性外,还可以从Cypher查询返回整个路径。要返回路径作为查询的结果,将需要给它一个标识符并能对它做出引用。那么,在return语句中通过指定标识符就可以返回引用的路径。

MATCH (n:Job) WHERE n.name="EXM" WITH n 
MATCH recPath = (:Job) - [d:DEPEND] -> (b:Job) 
WHERE b.email =~ /.*@gmail.com/
RETURN d,recPath

④ 分页结果
结果中包含很多实体,可能需要将结果分成几页以显示在网页上。要对Cypher查询结果进行分页,Neo4j有三个简单明了的语句。
order —— 在分页之前,对结果进行排序,因此分页返回的结果是一致的,无论是往前还是往后分页。
skip —— 划分结果集以便跳到指定的页。
limit —— 以页面尺寸限制返回结果的数量。

MATCH (job:job)
WHERE job.name = "EXM"
RETURN job
ORDER BY job.name
SKIP 3
LIMIT 25

高级Cypher

聚合

就像在SQL中的GROUP BY一样,Cypher支持查询中的聚合函数。不是使用一个专用GROUP BY语句,Cypher中的分组关键词被定义为所有的查询非聚合结果。
Cypher支持SQL的所有常用的聚合函数:SUM的数值求和、AVG计算平均值到MAX和MIN寻找数值属性中的最大值和最小值。

函数

TYPE函数
查找一个关系的类型。下面的例子演示了“每一类型有多少个关系开始于或结束于job名为EXM的节点?”

start n = node:job(name = "EXM")
MATCH n - [rel] - ()
WITH TYPE(rel), count(*)

常用的函数如下:
HAS(graphEntity.propertyName) —— 如果一个节点或关系具有给定名字的属性存在,则返回true。
NODES(path) —— 把一个路径转换成一个可迭代的节点集。
ALL(x in collection where predicate(x)) —— 如果collection中的每一个单个元素匹配了给定的predicate,则返回true。
NONE(x in collection where predicate(x)) —— 如果提供的集合中没有元素匹配谓词表述,返回true;否则,返回false。
ANY(x in collection where predicate(x)) —— 如果至少有一个元素匹配谓词表述,返回true;如果没有匹配的,返回false。
SINGLE(x in collection where predicate(x)) —— 如果正好有一个元素匹配谓词表述,返回true;如果没有或多于一个匹配的,这个函数返回false。

with语句的管道功能

在Cypher中,可以将一个查询的输出链接到另一个查询中,从而创建功能强大的图形结构。Cypher中的链(或管道)语句是with。
如果问题涉及在聚合函数上的过滤。在SQL中,在聚合函数上过滤是由HAVING语句完成的,但是Cypher并不支持这个。而在Cypher中可以使用with,就像下面的程序演示的一样。

start n = node(1)
MATCH n - [rel] - ()
WITH TYPE(rel) as type, count(*) as count
WHERE count > 1
RETURN type,count;

注意:在被用作链接查询之前命名with语句中的输出字段是强制性的!

总结

本文把常用的Cypher语言用法结合实际查询例子简要的介绍了一下,了解了Cypher之后,其实我们就可以使用Spring Data Neo4j(SDN)进行简单的开发了。下一篇文章将会介绍SDN的内容。

上一篇 下一篇

猜你喜欢

热点阅读