所以我在neo4j中有一个有向图,它有两个节点类型,比如A和B.基本上在顶部A指向很多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 - > A5 - > 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 Client - Getting a Path from a Node to its Root),我能够获得以下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的每个路径,但如果有很多这样的话,那就不是非常有效,特别是如果有一些漂亮的密码方式可以做到这一点。到目前为止,感谢您的帮助!
答案 0 :(得分:1)
你可以使用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
克里斯
答案 1 :(得分:0)
我的第一个答案是用一个有效的查询编辑的。
BTW在尝试查找此查询时,我发现了以下内容:
当尝试过滤节点集合(p)时,如果没有展开,标识符不会被视为节点,而是作为集合,我不知道它是否是预期的行为:
以下查询将失败,表示标识符s是集合,而预期是节点
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