如何使用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的话,这不是很有效特别是如果有一些巧妙的方法来做这件事。到目前为止,谢谢你的帮助!
你可以像这样使用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