Cypher中通过多个路径地址选择节点列表

Meh*_*ran 3 neo4j cypher

考虑以下密码:

MATCH (n{name: "John"})-[:Colleague]-(m) RETURN m;
Run Code Online (Sandbox Code Playgroud)

此查询Colleague(s)找到John(s). 现在另一个:

MATCH (n{name: "John"})-[:Friend]-()-[:Colleague]-(m) RETURN m;
Run Code Online (Sandbox Code Playgroud)

这是一个发现Colleague(s)John(s)' Friend(s)。现在是最后一个:

MATCH (n{name: "John"})-[:Colleague]-()-[:Friend]-(m) RETURN m;
Run Code Online (Sandbox Code Playgroud)

最后,这个发现Friend(s)John(s)' Colleague(s)。我正在寻找的是一个 Cypher 查询,它找到给定查询找到的所有节点的并集。

请注意,这只是一个示例。我实际上在这里问的是如何使用多个路径找到一组节点?就像是:

MATCH (n{name: "John"})
    -[:Colleague]- /
    -[:Friend]-()-[:Colleague]- /
    -[:Colleague]-()-[:Friend]-
    (m) RETURN m;
Run Code Online (Sandbox Code Playgroud)

Inv*_*con 6

在这种特殊情况下,您可以使用具有多种关系类型的可变长度关系。然而,为了防止不良路径(同事的同事、朋友的朋友以及只是朋友),我们必须进行一些额外的过滤,以确保路径中至少存在一个同事关系。

MATCH (n{name: "John"})-[r:Colleague|Friend*1..2]-(m) 
WHERE 'Colleague' in [rel in r | type(rel)]
RETURN m;
Run Code Online (Sandbox Code Playgroud)

另外,我强烈建议您在节点上使用标签,并在标签/名称组合上使用索引,以便快速查找 John 节点,而不必检查图中的每个节点。

该查询的性能不如执行 UNION 的查询,但通过索引查找和仅两次遍历,没有太多关系,它应该可以正常工作。