概述
使用语句CALL
调用子查询,每次通过传入的别名获取一条记录,执行子查询。CALL
子查询优化了资源管理,从而降低内存开销,提高查询效率,在处理大型数据集时效果尤为明显。
<call subqueries statement> ::=
[ "OPTIONAL" ] "CALL" [ "(" <variable list> ")" ] "{"
<statement block>
"}"
详情
- 可在
<variable list>
中包含一或多个来自前置查询的变量(用逗号分隔),这些变量会传入CALL
中。如果未指定,则自动传入所有可用变量。 - 子查询相关操作在
<statement block>
中定义,可用于多种目的,如数据检索、修改和其他处理任务。 - 当子查询使用
RETURN
语句输出结果时,每个输出行会附加到相应输入行的右侧。如果子查询没有产生输出,则丢弃对应输入行。如果子查询产生多个输出行,则重复对应的输入行,将结果和输入一一对应连接。 - 以修改数据为目的的子查询可能不包含
RETURN
语句。这种情况下,子查询执行前后,输入输出行数不变。 - 子查询返回为空时可以使用关键字
OPTIONAL
,使用后会返回null
值。
示例图集
以下示例根据该图集运行:
在空图集中运行以下语句创建示例图集:
INSERT (rowlock:User {_id:'U01', name:'rowlock'}),
(brainy:User {_id:'U02', name:'Brainy'}),
(purplechalk:User {_id:'U03', name:'purplechalk'}),
(mochaeach:User {_id:'U04', name:'mochaeach'}),
(lionbower:User {_id:'U05', name:'lionbower'}),
(c01:Club {_id:'C01'}),
(c02:Club {_id:'C02'}),
(rowlock)-[:Follows]->(brainy),
(mochaeach)-[:Follows]->(brainy),
(brainy)-[:Follows]->(purplechalk),
(lionbower)-[:Follows]->(purplechalk),
(brainy)-[:Joins]->(c01),
(lionbower)-[:Joins]->(c01),
(brainy)-[:Joins]->(c02),
(mochaeach)-[:Joins]->(c02)
查询
查找每个用户加入的俱乐部:
MATCH (u:User)
CALL (u) {
MATCH (u)-[:Joins]-(c:Club)
RETURN c
}
RETURN u.name, c._id
结果:
u.name | c._id |
---|---|
mochaeach | C02 |
Brainy | C01 |
Brainy | C02 |
lionbower | C01 |
聚合
计算俱乐部成员的粉丝数:
MATCH (u:User)-[:Joins]-(c:Club)
CALL (u) {
MATCH (u)<-[:Follows]-(follower)
RETURN COUNT(follower) AS followersNo
}
RETURN u.name, c._id, followersNo
结果:
u.name | c._id | followersNo |
---|---|---|
mochaeach | C02 | 0 |
Brainy | C01 | 2 |
Brainy | C02 | 2 |
lionbower | C01 | 0 |
数据修改
为标签为Joins
的边设定rates
属性值:
FOR score IN [1,2,3,4]
CALL (score) {
MATCH ()-[e:Joins WHERE e.rates IS NULL]-() LIMIT 1
SET e.rates = score
RETURN e
}
RETURN e
结果: e
_uuid |
_from |
_to |
_from_uuid |
_to_uuid |
schema |
values |
---|---|---|---|---|---|---|
Sys-gen | U04 | C02 | UUID of U04 | UUID of C02 | Joins | {rates: 1} |
Sys-gen | U02 | C01 | UUID of U02 | UUID of C01 | Joins | {rates: 2} |
Sys-gen | U02 | C02 | UUID of U02 | UUID of C02 | Joins | {rates: 3} |
Sys-gen | U05 | C01 | UUID of U05 | UUID of C01 | Joins | {rates: 4} |
传入多个变量
判断由边@Follows
连接的任意两个用户是否加入了同一个俱乐部:
MATCH (u1:User)<-[:Follows]-(u2:User)
CALL (u1, u2) {
OPTIONAL MATCH p = (u1)-(:Club)-(u2)
RETURN p
}
RETURN u1.name, u2.name,
CASE WHEN p IS NOT NULL THEN "Y"
ELSE "N" END AS sameClub
结果:
u1.name | u2.name | sameClub |
---|---|---|
Brainy | rowlock | N |
Brainy | mochaeach | Y |
purplechalk | Brainy | N |
purplechalk | lionbower | N |
子查询执行顺序
子查询的执行顺序并未预先确定。如需指定执行顺序,须在CALL
前使用ORDER BY
语句来强制执行该顺序。
本条查询统计每个用户的粉丝数。这里的子查询将根据升序排列的用户名称依次执行:
MATCH (u:User)
ORDER BY u.name
CALL (u) {
MATCH (u)<-[:Follows]-(follower)
RETURN COUNT(follower) AS followersNo
}
RETURN u.name, followersNo
结果:
u.name | followersNo |
---|---|
Brainy | 3 |
lionbower | 0 |
mochaeach | 0 |
purplechalk | 2 |
rowlock | 0 |