条件性 Cypher 执行
查询有时需要条件执行逻辑,这在 Cypher 中无法充分表达。条件执行过程模拟了 if/else 结构,其中提供的布尔条件决定了哪个 Cypher 查询被执行。
过程与函数概述
可用过程和函数描述如下
限定名称 | 类型 |
---|---|
apoc.when |
|
apoc.do.when |
|
apoc.case |
|
apoc.do.case |
|
WHEN 过程
对于 if/else 条件逻辑,when 过程允许指定 ifQuery 和 elseQuery。如果条件为 true,将运行 ifQuery;否则,将运行 elseQuery。
签名 |
---|
apoc.when(condition :: BOOLEAN, ifQuery :: STRING, elseQuery = :: STRING, params = {} :: MAP) :: (value :: MAP) |
apoc.do.when(condition :: BOOLEAN, ifQuery :: STRING, elseQuery = :: STRING, params = {} :: MAP) :: (value :: MAP) |
CALL apoc.when(
condition: BOOLEAN,
ifQuery: STRING,
elseQuery: STRING,
params: MAP)
YIELD value
CALL apoc.do.when(
condition: BOOLEAN,
ifQuery: STRING,
elseQuery: STRING,
params: MAP)
YIELD value
例如,要匹配距离起始节点一跳和两跳的邻居节点,并返回一个较小的集合(一跳或两跳的节点),请运行以下查询
MATCH (start:Node)-[:REL]->(a)-[:REL]->(b)
WITH collect(distinct a) as aNodes, collect(distinct b) as bNodes
CALL apoc.when(
size(aNodes) <= size(bNodes),
'RETURN aNodes as resultNodes',
'RETURN bNodes as resultNodes',
{aNodes:aNodes, bNodes:bNodes})
YIELD value
RETURN value.resultNodes as resultNodes
在账户可能被视为可疑的情况下(同时继续其他查询操作),要有条件地设置或创建图元素,请使用过程 apoc.do.when
。
MATCH (acc:Account)
OPTIONAL MATCH (acc)-[r:ACCESSED_BY]->(suspect:User)
WHERE suspect.id in {suspiciousUsersIdList}
CALL apoc.do.when(
r IS NOT NULL,
'SET acc:Suspicious',
'',
{acc:acc})
YIELD value
// ignore value and continue
WITH acc
...
CASE 过程
对于更复杂的条件逻辑,case 过程允许使用可变长度的条件/查询对列表,其中第一个评估为 true 的条件后面的查询将被执行。如果所有条件都为 false,则执行 elseQuery 块。
签名 |
---|
apoc.case(conditionals :: LIST<ANY>, elseQuery = :: STRING, params = {} :: MAP) :: (value :: MAP) |
apoc.do.case(conditionals :: LIST<ANY>, elseQuery = :: STRING, params = {} :: MAP) :: (value :: MAP) |
CALL apoc.case(
conditionals: List of alternating BOOLEAN/STRING,
elseQuery: STRING,
params: MAP)
YIELD value
CALL apoc.do.case(
conditionals: List of alternating BOOLEAN/STRING,
elseQuery: STRING,
params: MAP)
YIELD value
要在列中匹配选择节点,可以根据查询参数或图中已有的数据使用不同的 MATCH 子句。
MATCH (me:User {id:$myId})
CALL apoc.case([
$selection = 'friends', "RETURN [(me)-[:FRIENDS]-(friend) | friend] as selection",
$selection = 'coworkers', "RETURN [(me)-[:WORKS_AT*2]-(coworker) | coworker] as selection",
$selection = 'all', "RETURN apoc.coll.union([(me)-[:FRIENDS]-(friend) | friend], [(me)-[:WORKS_AT*2]-(coworker) | coworker]) as selection"],
'RETURN [] as selection',
{me:me}
)
YIELD value
RETURN value.selection as selection;
要根据值在两个节点之间创建不同的关系类型,请运行以下语句
MATCH (me:User {id:$myId})
MATCH (friend:User {id:$friendId})
CALL apoc.do.case([
$selection = 'friends', "MERGE (me)-[rel:FRIENDS]->(friend) RETURN rel",
$selection = 'coworkers', "MERGE (me)-[rel:CO_WORKER]->(friend) RETURN rel"],
'MERGE (me)-[rel:CONNECTED]->(friend) RETURN rel',
{me:me, friend:friend}
)
YIELD value
RETURN value.rel as rel;