概述
使用CALL
语句可调用一个内联过程或具名过程。
调用内联过程
内联过程是一种嵌入在查询中的用户自定义过程,通常用于执行子查询或进行数据修改。它能实现循环等复杂逻辑,并通过更有效地管理资源(尤其在处理大型图时)来提高效率,从而减少内存开销。
<call inline procedure statement> ::=
[ "OPTIONAL" ] "CALL" [ "(" [ <variable reference list> ] ")" ] "{"
<statement block>
"}"
<variable reference list> ::=
<variable reference> [ { "," <variable reference> }... ]
详情
- 可将查询前文定义的变量导入
CALL
。若未显式指定,默认导入所有当前变量。 - 每条被导入的记录都会由
CALL
内部的<statement block>
独立处理。 - 用于子查询时,
<statement block>
必须以RETURN
语句结尾,将变量输出至外层查询:- 每个返回的变量会成为中间结果表的新列。
- 若一个子查询未返回结果,则对应的导入记录将被丢弃。使用
OPTIONAL
关键字可处理这种情况——此时将生成null
值而非丢弃记录。 - 若返回多条结果,导入的行会相应复制。
- 用于数据修改时,可以没有
RETURN
语句。此时CALL
执行后中间结果表的记录数保持不变。
示例图

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 (c:Club)
CALL {
MATCH (c)<-[:Joins]-(u:User)
RETURN collect_list(u.name) AS members
}
RETURN c._id, members
结果:
c._id | members |
---|---|
C01 | ["Brainy","lionbower"] |
C02 | ["Brainy","mochaeach"] |
OPTIONAL CALL
查找每个C01
俱乐部成员的关注者,确保没有关注者的成员也能返回:
MATCH (c)<-[:Joins]-(u:User) WHERE c._id = "C01"
OPTIONAL CALL (u) {
MATCH (u)<-(follower:User)
RETURN collect_list(follower.name) AS followers
}
RETURN u.name, followers
结果:
u.name | followers |
---|---|
Brainy | ["rowlock","mochaeach"] |
lionbower | null |
子查询执行顺序
子查询的执行顺序不是确定的。如需指定执行顺序,可在CALL
前使用ORDER BY
来对记录进行排序。
本查询统计每个用户的关注者数量,这里的子查询根据升序排列的用户name
依次执行:
MATCH (u:User)
ORDER BY u.name
CALL {
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 |
数据修改
为Joins
边设定rates
属性值:
FOR score IN [1,2,3,4]
CALL {
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} |
调用具名过程
具名过程指系统中预定义、已注册的过程,比如算法,可通过CALL
语句按其名称进行调用。
<call named procedure statement> ::=
"CALL" <procedure reference> [ <yield clause> ]
<yield clause> ::=
"YIELD" <yield item> [ { "," <yield item> }... ]
<yield item> ::=
<column name> [ "AS" <binding variable> ]
详情
- 可使用
YIELD
子句将变量输出至外层查询。
执行算法
执行度中心性算法。注意,该算法在从当前图派生的HDC图my_hdc_graph
上运行。
CALL algo.degree.run("my_hdc_graph", {
direction: "in",
order: "desc"
}) YIELD r
RETURN r
更多可用算法请参阅图分析与算法文档。