鸟哥的Neo4j私房菜(二)

还是写在前面?

按照原计划系列的第二篇博文来介绍一下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句法由四个不同的部分组成, 每一部分都有一个特殊的规则:

  • start——查找图形中的起始节点。
  • match——匹配图形模式, 可以定位感兴趣数据的子图形。
  • where——基于某些标准过滤数据。
  • return——返回感兴趣的结果。

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可以指定编号查找起始节点
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
  • 过滤数据
    在一些情况下,需要对节点和关系再做一些过滤以决定返回哪些结果。与在关系数据库中的SQL查询相同,Cypher查询过滤使用where语句实现。
    可以通过属性值、正则表达式以及函数(has(property))过滤
MATCH (n:Job) WHERE n.name="EXM" WITH n 
MATCH (:Job) - [:DEPEND] -> (b:Job) 
WHERE b.email =~ /.*@gmail.com/
RETURN b
  • 获得结果
    Cypher查询的结果用return语句返回,return语句不仅仅能返回节点——也可以返回关系、节点和关系的属性,甚至子图形的整个路径。

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

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的内容。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容

  • 写在前面 从去年找工作结束之后,就一直没有再写博文了,不知不觉已经过去大半年了T_T。鸟哥也从学校正式步入职场,开...
    niaoge2016阅读 2,220评论 0 6
  • 冬天的早晨 显得格外寒冷 忽然窗帘外一阵鸡鸣声 扰人清梦 我起身 背着书包去学校 走在上学的路上 听见小鸟在歌唱 ...
    hwc阅读 495评论 0 2
  • 你的心是花粉 你的声音是花粉 你的目光是花粉 你的路是花粉 当风轻轻一吹 你的身体 扑向墙壁 游弋在空气 降落大地...
    宋温暖2020阅读 624评论 5 26