如何使用cypher检索neo4j图中两个节点之间的唯一路径列表

本文关键字:节点 两个 之间 列表 路径 唯一 检索 cypher 何使用 neo4j | 更新日期: 2023-09-27 18:13:51

所以我在neo4j中有一个有向图,它有两个节点类型,比如a和B。基本上在顶部a指向许多B,每个B指向许多a,递归地向下。像这样:

A1 -> B1, B2, B3

B1 -> A3, A4, A7

B2 -> A5, A6, A8

A3 -> B3

A4 -> B3

A5 -> B3

B3 -> A9

无论如何,取两个不同的A,我想运行一个查询来找出这两个A之间的所有唯一路径。因此,给定上面的A1和A9,我希望输出如下:

A1 -> B1 -> A3 -> B3 -> A9,

A1 -> B1 -> A4 -> B3 -> A9,

A1 -> B2 -> B3 -> A9,

A1 -> B3 -> A9

如果可能的话,我也想从同一个查询中去掉B(因为它们对于这个特定的情况不是必需的),所以最终结果如下:

A1 -> A3 -> A9,

A1 -> A4 -> A9,

A1 -> A5 -> A9,

A1 -> A9

如果没有,我可以在查询之后手动执行,尽管在查询内显然会更好。我该如何形成这个查询呢?

到目前为止,我有这样的东西:

var dic = new Dictionary<string, object> {{a1.toString(), a1}, {a2.toString(), a2}};
var query = _graphClient.Cypher
    .Start(dic)
    .Match(String.Format("p={0}-[*]->{1}", a1.toString(), a2.toString()))
    //I don't know what goes here exactly... .Return(something)
    .Results;
return query.Single();

我想我需要用多个密码查询做一些事情,以便剔除B。也许可以使用这个作为中介并将其应用于任何深度:

a1-[]->b-[]->a2
return a1, a2;

任何帮助将是惊人的!提前谢谢你!!

有了Christophe Willemsen的评论和这篇文章(Neo4j .NET客户端-从节点到其根的路径),我能够得到以下c#代码,除了从路径中删除B之外,它做了所有事情:

var query = _graphClient.Cypher
    .Match("p = (a2:A)-[*]->(a1:A)")
    //Where and AndWhere's for matching a1 and a2 as necessary
    .Return<IEnumerable<A>>("nodes(p)")
    .OrderByDescending("length(p)")
    .Results
    .SelectMany(result => new List<List<A>> {result.ToList()});
return query.ToList();

如果有人知道如何指定节点(p)只返回A,那应该可以做到。我可以简单地遍历每条路径,去掉B,但如果有很多B的话,这不是很有效特别是如果有一些巧妙的方法来做这件事。到目前为止,谢谢你的帮助!

如何使用cypher检索neo4j图中两个节点之间的唯一路径列表

你可以像这样使用allShortestPaths算法

MATCH (a:A { name:'A1' }),(aa:A { name:'A8' }), p = allShortestPaths((a)-[*]-(aa))
RETURN DISTINCT (p), collect(nodes(p)) AS x
ORDER BY length(p) DESC 
LIMIT 5

我已经在这里设置了一个neo4j控制台作为沙盒:http://console.neo4j.org/?id=pjf2qg

我如何能够从结果btw中删除B节点的斗争

更新

我最终只从路径中提取了A标记的节点:

MATCH (a:A {name:'A1'}),(aa:A {name:'A8'}),
p = allShortestPaths((a)-[*]-(aa))
WITH DISTINCT(p) as pths, COLLECT(nodes(p)) as x
UNWIND(x) as u
WITH FILTER(s IN u WHERE 'A' IN labels(s)) AS zz, pths as paths
RETURN paths, zz
克里斯

我的第一个回答是用一个工作查询编辑的。

BTW当试图找到这个查询时,我发现了以下内容:

当尝试过滤节点集合(p)时,没有展开,标识符不被视为节点,而是作为集合,我不知道这是否是预期的行为:

下面的查询将失败,因为标识符s是一个集合,并且期望有一个Node

MATCH (a:A {name:'A1'}),(aa:A {name:'A8'}),
p = allShortestPaths((a)-[*]-(aa))
WITH p as paths, COLLECT(nodes(p)) as x
WITH filter(s IN x WHERE 'A' IN labels(s)) AS zz
RETURN zz