给出以下架构/数据集:
(a:A1)-[ONE]->(b:B1)-[TWO]->(c:C1)
(a:A1)-[ONE]->(b:B1)-[TWO]->(c:C2)
(a:A1)-[ONE]->(b:B2)-[TWO]->(c:C3)
(a:A2)-[ONE]->(b:B3)
(a:A2)-[ONE]->(b:B4)-[TWO]->(c:C4)
(a:A2)
我正在尝试汇总一些a
属性的查询,b
属性列表(字符串列表),最后是c
属性列表列表(字符串列表)。我很接近使用collect()
,但遇到了一个跟踪哪个c
属于哪个b
的问题。
我寻求的查询每a
会产生一行(给定数据集为2行),注意数据可以是稀疏的,因此结果中的空数组表示层次结构:
"A1"
,["B1", "B2"]
,[["C1","C2"],["C3"]]
"A2"
,["B3", "B4"]
,[[],["C4"]]
答案 0 :(得分:1)
使用COLLECT
[或任何其他聚合]聚合时,另一个未收集的 [ unaggregated ]值row用作聚合键,因此只有共享所有其他值的行才会匹配。对于您的查询,您基本上需要在两个单独的步骤中堆叠COLLECT
,以便首先获取由c
和 {{1}键入的a
列表然后收集所有b
s 和 b
所有c
的所有列表,如下所示:
a
您可以将MATCH (a) - [:ONE] -> (b)
OPTIONAL MATCH (b) - [:TWO] -> (c)
WITH a, b, COLLECT(c.property) AS cs
WITH a, COLLECT(b.property) AS bs, COLLECT(cs) AS cs_per_b
RETURN a.property, bs, cs_per_b
替换为您希望从节点获取的任何属性,如果它不是节点属性,而是标签或其他值,则只需替换property
中的整个表达式。如果没有cs,你也可以通过这种方式获得cs_per_b中的空列表。
答案 1 :(得分:0)
虽然您的问题表明您要列出节点"属性",但您的示例结果会列出节点标签。
要显示节点标签,以下查询应该有效:
MATCH (a)-[:ONE]->(b)
OPTIONAL MATCH (b)-[:TWO]->(c)
WITH a, b, COLLECT(DISTINCT LABELS(c)[0]) AS lcs
RETURN LABELS(a)[0] AS la, COLLECT(LABELS(b)[0]) AS lb, COLLECT(lcs) AS lc;
该查询假定使用ONE
和TWO
关系类型来区分Ax
,Bx
和Cx
节点标签就足够了,并且那些节点只有一个标签。它使用OPTIONAL MATCH
作为TWO
关系,因为您的示例结果意味着它是可选的。