在neo4j中,从列表中提取唯一元素

时间:2019-10-08 13:43:57

标签: neo4j cypher

我有一个数据库,其中的节点和关系是这样创建的:

create ({foo: 1})-[:r]->({foo: 1}), ({foo: 1})-[:r]->({foo: 2}), ({foo: 1})-[:r]->({foo: 2})

对于每个路径,我可以通过以下方式生成属性列表:

MATCH path = (start)-[*]->(end)
WHERE NOT ()-->(start) and NOT (end)-->()
RETURN [node in nodes(path) | node.foo] as foos

返回

foos
------
[1, 1]
[1, 2]
[1, 2]

但是我只希望每个列表中都有不同的属性。

受到Cypher: Extract unique values from collection的启发

MATCH path = (start)-[*]->(end)
WHERE NOT ()-->(start) and NOT (end)-->()
WITH [node in nodes(path) | node.foo] as foos
UNWIND foos as x
RETURN COLLECT(DISTINCT x) as foos_unique

但这为我提供了所有节点的独特属性:

foos_unique
----
[1, 2]

如何从每个列表中提取不同的元素,这样结果将是

foos_unique
------
[1]
[1, 2]
[1, 2]

2 个答案:

答案 0 :(得分:1)

[已更新]

REDUCE函数将帮助:

MATCH path = (start)-[*]->(end)
WHERE NOT ()-->(start) and NOT (end)-->()
RETURN REDUCE(s = [], n in NODES(path) |
  CASE WHEN NOT EXISTS(n.foo) OR n.foo IN s THEN s ELSE s + n.foo END) as foos

答案 1 :(得分:0)

这可以完成工作。无需收集唯一元素,我们可以像这样比较foostart的{​​{1}}:

end

输出为:

MATCH (start)-[*]->(end)
WHERE NOT ()-->(start) and NOT (end)-->()
WITH start.foo as foos, end.foo as fooe 
RETURN case when foos = fooe then [foos] else [foos, fooe] end as foos_unique