考虑关注Cyphers:
MATCH (n{name: "John"})-[:Colleague]-(m) RETURN m;
此查询查找Colleague(s)
的{{1}}。现在另一个:
John(s)
这个MATCH (n{name: "John"})-[:Friend]-()-[:Colleague]-(m) RETURN m;
Colleague(s)
John(s)'
。现在是最后一个:
Friend(s)
最后,这个人找到MATCH (n{name: "John"})-[:Colleague]-()-[:Friend]-(m) RETURN m;
Friend(s)
的{{1}}。我正在寻找的是Cypher查询,它查找给定查询找到的所有节点的并集。
请注意,这只是一个例子。我在这里问的实际问题是如何使用多个路径找到一组节点?类似的东西:
John(s)'
答案 0 :(得分:4)
在这种特殊情况下,您可以使用具有多种关系类型的可变长度关系。但是,为了防止不良路径(同事,朋友的朋友和朋友的同事),我们必须做一些额外的过滤,以确保路径中至少有一个同事关系。
MATCH (n{name: "John"})-[r:Colleague|Friend*1..2]-(m)
WHERE 'Colleague' in [rel in r | type(rel)]
RETURN m;
另外,我强烈建议您在节点上使用标签,并在标签/名称组合上使用索引,这样您对John节点的查找速度很快,而不必检查图中的每个节点。 / p>
这个查询不像执行UNION的查询那样高效,但是通过索引查找和只有两次遍历,关系不是太多,它应该可以正常工作。
答案 1 :(得分:2)
如何简单地使用UNION?试试吧:
MATCH (n{name: "John"})-[:Colleague]-(m)
RETURN m as node
UNION
MATCH (n{name: "John"})-[:Friend]-()-[:Colleague]-(m)
RETURN m as node
UNION
MATCH (n{name: "John"})-[:Colleague]-()-[:Friend]-(m)
RETURN m as node
答案 2 :(得分:2)
您可以跨多个匹配重用变量来引用同一节点(JOIN模式)。实施例
MATCH (n{name: "John"})-[:Colleague]-(m)
MATCH (n)-[:Friend]-()-[:Colleague]-(m)
MATCH (n)-[:Colleague]-()-[:Friend]-(m)
RETURN m;
在这里," John"匹配一次,并用作每个匹配的开始,m是每个匹配的有趣节点的连接。如果" John"有多个实例,则此查询将分别处理所有这些实例。如果所有" Johns"应该被视为同一个人,而不仅仅是重用n。
如果你想要UNION而不是JOIN,你可以像这样收集它们
MATCH (n{name: "John"})
OPTIONAL MATCH (n)-[:Colleague]-(c)
OPTIONAL MATCH (c)-[:Friend]-(fc)
OPTIONAL MATCH (n)-[:Friend]-()-[:Colleague]-(fc)
WITH c+collect(fc)+collect(cf) AS nodez
UNWIND nodez AS m
RETURN DISTINCT m;
答案 3 :(得分:1)
为处理UNION查询添加单独的答案,同时保留处理联合结果的能力。
我们实际上有一篇关于post-UNION processing的知识库文章,其中有几种不同的方法。
使用APOC程序,您可以在apoc.cypher.run()
内执行UNION,并获取返回的联合结果并继续对它们进行操作。
答案 4 :(得分:1)
这个简单的查询应该有效:
MATCH p=({name: "John"})-[:Friend*0..1]-()-[:Colleague]-()-[:Friend*0..1]-(m)
WHERE LENGTH(p) <= 2
RETURN m;
它使用可变长度模式*0..1
使Friend
关系可选。 WHERE
子句筛选出长度超过2个关系的路径。