概述
使用CALL
语句可构建子查询,每次使用导入的变量的一条记录。CALL
子查询可优化资源管理,降低内存开销,从而提高查询效率,在处理大型数据集时效果尤为明显。
<call statement> ::=
[ "OPTIONAL" ] "CALL" [ "(" [ <variable list> ] ")" ] "{"
<statement block>
"}"
<variable list> ::=
<variable reference> [ { "," <variable reference> }... ]
详情
<variable list>
可包含一或多个(逗号分隔)来自前置查询的变量,这些变量会导入CALL
中。如果忽略,隐式传入所有变量。- 子查询相关操作在
<statement block>
中定义,可用于多种目的,如数据检索和修改等。 - 当子查询使用
RETURN
语句输出结果时:- 每个输出记录会附加到相应输入记录右侧。
- 如果子查询没有产生记录,则丢弃对应输入记录。
- 如果子查询产生多个输出记录,则复制对应的输入记录。
- 修改数据的子查询可能不包含
RETURN
语句。这种情况下,子查询执行前后,输入输出记录数不变。 - 子查询无返回时可以使用关键字
OPTIONAL
返回null
值。
示例图

CREATE GRAPH myGraph {
NODE User ({name string}),
NODE Club (),
EDGE Follows ()-[{}]->(),
EDGE Joins ()-[{rates uint32}]->()
} PARTITION BY HASH(Crc32) SHARDS [1]
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
语句来规定执行顺序。
本查询统计每个用户的关注者数量,这里的子查询根据升序排列的用户name
依次执行:
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 | 2 |
lionbower | 0 |
mochaeach | 0 |
purplechalk | 2 |
rowlock | 0 |