neo4j:如果为else,则使用密码

aydmsdu9  于 2023-04-11  发布在  其他
关注(0)|答案(3)|浏览(156)

我有三种类型的节点:FOLDER、TYPE_A、TYPE_B和一个关系:包含;
我在编写cypher时遇到了困难,在一个查询中,获取这个:

if(folder CONTAINS TYPE_A) {
   return ids of TYPE_A
} else if (folder CONTAINS TYPE_B) {
  then return ids of TYPE_B
} else {
  return empty array;
}

有人能帮忙吗

isr3a4wc

isr3a4wc1#

对于特定文件夹,一个选项是:

MATCH (n:FOLDER)
WHERE n.key = 1
OPTIONAL MATCH (n)--(m)
WITH DISTINCT labels(m) AS type, COLLECT (id(m)) AS res
ORDER BY type[0]
LIMIT 1
RETURN res

它返回样本数据的预期输出:

MERGE (a1:FOLDER {key:1})    
MERGE (a2:TYPE_A {key:2})   
MERGE (a3:TYPE_A {key:3})
MERGE (a4:TYPE_B {key:4})
MERGE (b1:FOLDER {key:5})
MERGE (b2:TYPE_B {key:6})
MERGE (c1:FOLDER {key:7})

MERGE (a1)-[:CONTAINS]-(a2)
MERGE (a1)-[:CONTAINS]-(a3)
MERGE (a1)-[:CONTAINS]-(a4)
MERGE (b1)-[:CONTAINS]-(b2)

如果要在一个查询中获得所有文件夹的结果,可以执行以下操作:

MATCH (n:FOLDER)
OPTIONAL MATCH (n)--(m)
WITH DISTINCT labels(m) AS type, COLLECT (id(m)) AS res, id(n) AS folder
ORDER BY type[0]
WITH DISTINCT folder, COLLECT (res) AS res
RETURN res[0], folder
dgjrabp2

dgjrabp22#

一种方法是使用apoc.do.when有条件地获取TYPE_Bids,当不存在TYPE_A节点时。如下所示:

MATCH (n:FOLDER)
OPTIONAL MATCH (n)-[:CONTAINS]-(m:TYPE_A)
WITH n, collect(id(m)) AS typeAIds
CALL apoc.do.when(
   size(typeAIds) = 0, 
   'OPTIONAL MATCH (n)-[:CONTAINS]-(m:TYPE_B) WITH n, collect(id(m)) AS typeBIds RETURN typeBIds', 
   'RETURN [] as typeBIds', 
   {n: n}
) 
YIELD value
RETURN n, typeAIds + value.typeBIds AS ids

在这个查询中,我们首先获取TYPE_A节点id并将它们收集在一个数组中。如果这些ids不存在,那么我们在apoc.do.when中获取TYPE_B节点id。最后,我们返回输出。这是一个更优化的方法,因为我们只在需要时获取关系。您需要安装,APOC库来执行此查询。同一查询的另一个变体是:

MATCH (n:FOLDER)
CALL apoc.do.when(
    SIZE([(n)-[:CONTAINS]-(:TYPE_A) | 1]) <> 0, 
    'OPTIONAL MATCH (n)-[:CONTAINS]-(m:TYPE_A) WITH n, collect(id(m)) AS typeAIds RETURN typeAIds', 
    'RETURN [] as typeAIds', 
    {n: n}
)
YIELD value AS v1
CALL apoc.do.when(
    SIZE([(n)-[:CONTAINS]-(:TYPE_B) | 1]) <> 0 AND SIZE(v1.typeAIds) = 0, 
    'OPTIONAL MATCH (n)-[:CONTAINS]-(m:TYPE_B) WITH n, collect(id(m)) AS typeBIds RETURN typeBIds', 
    'RETURN [] as typeBIds', 
    {n: n}
)
YIELD value AS v2
RETURN n, v1.typeAIds + v2.typeBIds AS ids
ih99xse1

ih99xse13#

这将返回ab列表(我们返回两个列表,如果一些文件夹甚至一些“类型”节点包含两个标签):

MATCH (f:FOLDER)-[:CONTAINS]->(ty:TYPE_A|TYPE_B)
WHERE f.id = 123
WITH REDUCE(s={a:[], b:[]}, t IN COLLECT(ty) |
  CASE WHEN ALL(w IN ['TYPE_A','TYPE_B'] WHERE w IN LABELS(t))
    THEN {a: s.a+t, b: s.b+t}
  CASE WHEN 'TYPE_A' IN LABELS(t)
    THEN {a: s.a+t, b: s.b}
  ELSE {a: s.a, b: s.b+t} END) AS x
RETURN x.a AS a, x.b AS b

查询使用 predicate 标签表达式(ty:TYPE_A|TYPE_B)来搜索以两个所需标签中的任一个结尾的“type”节点。neo4j 5.0中引入了对此类表达式的支持。
REDUCE函数用于遍历匹配的“type”节点以生成列表。CASE表达式用于对每个节点进行IF/THEN/ELSE处理。

相关问题