条件性 Cypher 执行

查询有时需要条件执行逻辑,这在 Cypher 中无法充分表达。条件执行过程模拟了 if/else 结构,其中提供的布尔条件决定了哪个 Cypher 查询被执行。

过程与函数概述

可用过程和函数描述如下

限定名称 类型

apoc.when
apoc.when(condition BOOLEAN, ifQuery STRING, elseQuery STRING, params MAP<STRING, ANY>) - 如果条件评估为 true,此过程将运行只读的 ifQuery;否则,将运行 elseQuery

过程

apoc.do.when
apoc.do.when(condition BOOLEAN, ifQuery STRING, elseQuery STRING, params MAP<STRING, ANY>) - 如果条件评估为 true,此过程将运行给定的读/写 ifQuery;否则,将运行 elseQuery

过程

apoc.case
apoc.case(conditionals LIST<ANY>, elseQuery STRING, params MAP) - 对于给定 LIST<ANY> 中的每一对条件和只读查询,此过程将运行第一个条件评估为 true 的查询。如果所有条件均为 false,则将运行 ELSE 查询。

过程

apoc.do.case
apoc.do.case(conditionals LIST<ANY>, elseQuery STRING, params MAP<STRING, ANY>) - 对于给定 LIST<ANY> 中的每一对条件查询,此过程将运行第一个条件评估为 true 的查询。如果所有条件均为 false,则将运行 ELSE 查询。

过程

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;
© . All rights reserved.