Neo4j之三_复杂MATCH语句

本文以解决以下问题为线索:需求:匹配模式:A–>B–>C要求:1.A点的入度为0,出度为1;2.B点的入度为1,出度为1;3.C点的入度为1,出度为0;MATCH的进阶用法有以下三种:WHERE中条件可以看作是模式的一部分,MATCH语句的一部分。1.多模式:MATCH p1..., p2=... [WHERE...]2.多MATCH语句MATCH ... [WHERE...]MATCH ... [WHERE...]3.接WITH:这个本质上是以聚合函数作为判断
摘要由CSDN通过智能技术生成

一 MATCH语法

WHERE中条件可以看作是模式的一部分,WHERE子句可视为MATCH子句的一部分。

MATCH的进阶用法有以下三种:

1.多模式:

MATCH p1..., p2=... [WHERE...]

2.多MATCH语句

MATCH ... [WHERE...]
MATCH ... [WHERE...]

3.MATCH…WITH:这个最终是为了以聚合函数作为判断条件

MATCH ... [WHERE...]
WITH ... [WHERE...]

二 MATCH作用

MATCH以模式匹配的方式对整个graph进行查找,并返回结果集。

查找过程:

  1. MATCH在整个graph中进行一次模式匹配,将得到的结果打包成一个结果元组,放入结果集;
  2. MATCH重复以上步骤,直到不再有新的结果。

查找结果:

  1. 结果不一定是单个值(结点/关系/路径),可以是多个值打包成的元组,如:(p1,p2);
    【注意:当查询中有不相连的pattern时,会有Warning,并提示将建立笛卡尔结果;所谓笛卡尔结果就是MySQL中JOIN】
  2. 结果元组中包含多个路径值时,各路径不能包含相同的边,可以包含相同的点,如:p1为A–>B–>C,p2不能为A–>B,但是p2可为B–>D。

注意:

  1. MATCH操作的是模式pattern,结点的pattern是小括号;WITH、RETURN中操作的是变量,不需要小括号。
  2. MATCH返回的是一个结果集,结果集的元素为MATCH中pattern所包含的变量形成的元组;
  3. MATCH搜索的范围总是整个graph;多个MATCH子句串联时,每个都是重新从graph中查找。
  4. RETURN、WITH的搜索范围是中间结果表。

三 MATCH用法详解

3.1 MATCH…WHERE…RETURN…

路径模式也是一种约束条件,既可以放在MATCH子句中,也可以放在WHERE子句中。仅从语法上看,两种方式能实现相同的功能。那么到底放在哪里更好?可从执行效率上比较。

以下三条语句执行结果相同,但耗时相差巨大:

代码一:执行耗时:250 ms
MATCH (a:Blog{mid:'IbjCn93Bs'})-[*5]->(b:Blog) return b;

代码二:执行耗时:254 ms.
MATCH (a:Blog)-[*5]->(b:Blog) where a.mid='IbjCn93Bs' return b

代码三:执行耗时:165088 ms.
MATCH (a:Blog{mid:'IbjCn93Bs'}),(b:Blog) where (a)-[*5]->(b) return b;

分析/结论:
1.由代码一和代码二可知:模式放在MATCH中时,属性值约束放在MATCH或WHERE中执行时间基本相同。
2.由代码一和代码三可知:模式放在MATCH中执行效率远高于放在WHERE中。

可见,应该将模式相关的约束条件放到MATCH中,属性值相关的约束条件放哪都可以。

补充:
为什么会想到代码三这样的写法?
个人认为代码三这样的写法语义上更加清晰,在MATCH指明想要查找的目标是结点而不是路径,将与目标结点相关的所有约束(模式、属性值)都放到WHERE中,最后RETURN返回目标结点。
但既然效率上相差巨大,那自然不做此考虑了。

为什么代码三执行的这么慢?
个人猜想是:MATCH和WHERE是先后执行的,MATCH找到并保存所有符合模式的中间结果后,再由WHERE进一步判断。这样的话,MATCH中约束越宽松找到的中间结果越多,之后WHERE判断的次数也越多。
假设:代码一中访问整个图找到中间结果10个,之后进行10次WHERE判断即可;代码三中访问整个图找到中间结果1000个,之后再进行1000次WHERE判断。
另外,注意到,代码三中是不相连的模式,变量b模式找到的是所有结点,再与a形成笛卡尔积,数量就很大了。

3.2 MATCH p1=… , p2=…

https://neo4j.com/docs/cypher-manual/current/introduction/uniqueness/

MATCH p1=(a)-->(b),p2=(c)-->(d)

参照2.X中对MATCH匹配过程的理解,进行循环多次匹配后,MATCH返回的结果集如下:

[(p1_1,p2_1),(p1_2,p2_2)...]

对应表格形式:

p1 p2
p1_1 p2_1
p1_1 p2_2
p1_1 p2_3

匹配多个模式时,Neo4j自动约束返回的一个结果(如:(p1_1,p2_1))中不能存在重复的边。验证如下:

graph:整个数据库
在这里插入图片描述

3.2.1 测试一:
match p1=(a:Test)-->(b)-->(c),p2=(a)-->()
return p1,p2

结果: no records
分析:

  1. 第一次匹配,找到p1=(717069)–>(717068)–>(717650),再找p2,由于(717069)只有一条出去的边(717069)–>(717068),而该边已存在于p1中,所以p2不存在,所以结果(p1,p2)不存在。
  2. 第二次匹配,找到p1=(717070)–>(717028)–>(717649),同理p2不存在,(p1,p2)不存在。
  3. 第三次匹配,找到p1=(717070)–>(717028)–>(717648),同理p2不存在,(p1,p2)不存在。

综上,结果集为空。

3.2.2 测试二:
match p1=(a:Test)-->(b)-->(c),p2=(b)-->()
return p1,p2

结果:
在这里插入图片描述
分析:

  1. 第一次匹配,找到p1=(717069)–>(717068)–>(717650),再找p2,p2不存在,(p1,p2)不存在。
  2. 第二次匹配,找到p1=(717070)–>(717028)–>(717649),p2=(717028)–>(717648),得(p1_1,p2_1)。
  3. 第三次匹配,找到p1=(717070)–>(717028)–>(717648),p2=(717028)–>(717649),得(p1_2,p2_2)。

综上,结果集为[(p1_1,p2_1),(p1_2,p2_2)]。

3.3 MATCH…MATCH…

graph:整个数据库
在这里插入图片描述
MATCH、RETURN的功能通过以下测试详细说明:

3.3.1 测试一:
MATCH (a:Test)-->()-->()
WHERE id(a) in [717069,717070]
MATCH p=(a)-->()
RETURN p

结果:

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Neo4jMATCH语句是用于在Neo4j数据库中查询数据的一种查询语句MATCH语句可以用来匹配图中的节点和关系,并根据指定的条件返回满足条件的结果。 在MATCH语句中,可以指定节点之间的关系、节点的属性、节点的标签等条件来进行查询。可以使用箭头符号(->、<-、-)来表示节点之间的关系,还可以使用圆括号和冒号来指定节点的属性和标签。 例如,可以使用MATCH语句查询节点之间的关系,并返回满足条件的结果。可以使用WHERE子句来指定查询条件。例如,MATCH (a)-->(b)表示匹配所有具有指定关系的节点,并返回满足条件的结果。 另外,MATCH语句还可以根据节点或关系的id进行查询。可以使用id()函数来获取节点或关系的id,并使用WHERE子句来指定查询条件。例如,MATCH (n) WHERE id(n)=0 RETURN n表示根据节点的id查询节点,并返回满足条件的结果。 总之,Neo4jMATCH语句是用于匹配图中的节点和关系,并根据指定的条件返回满足条件的结果的查询语句。可以根据节点之间的关系、节点的属性、节点的标签等条件来进行查询,并可以根据节点或关系的id进行查询。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Neo4j之三_复杂MATCH语句](https://blog.csdn.net/IMchg/article/details/108311630)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [neo4j语法-match](https://blog.csdn.net/qq_17616169/article/details/115390320)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值