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
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
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
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
3条答案
按热度按时间isr3a4wc1#
对于特定文件夹,一个选项是:
它返回样本数据的预期输出:
如果要在一个查询中获得所有文件夹的结果,可以执行以下操作:
dgjrabp22#
一种方法是使用
apoc.do.when
有条件地获取TYPE_B
的ids
,当不存在TYPE_A
节点时。如下所示:在这个查询中,我们首先获取
TYPE_A
节点id并将它们收集在一个数组中。如果这些ids
不存在,那么我们在apoc.do.when
中获取TYPE_B
节点id。最后,我们返回输出。这是一个更优化的方法,因为我们只在需要时获取关系。您需要安装,APOC
库来执行此查询。同一查询的另一个变体是:ih99xse13#
这将返回
a
和b
列表(我们返回两个列表,如果一些文件夹甚至一些“类型”节点包含两个标签):查询使用 predicate 标签表达式
(ty:TYPE_A|TYPE_B)
来搜索以两个所需标签中的任一个结尾的“type”节点。neo4j 5.0中引入了对此类表达式的支持。REDUCE函数用于遍历匹配的“type”节点以生成列表。CASE表达式用于对每个节点进行
IF/THEN/ELSE
处理。