使用Gremlin在图中找到避开给定顶点列表的最短路径?

时间:2011-08-31 10:07:04

标签: graph neo4j traversal gremlin

我需要使用Gremlin找到两个节点(顶点)之间的最短路径,同时避免给定顶点列表。

我已经拥有:

v.bothE.bothV.loop(2){!it.object.equals(y)}.paths>>1

获得我的最短路径。

我正在尝试类似的事情:

v.bothE.bothV.filter{it.name!="ignored"}.loop(3){!it.object.equals(y)}.paths>>1

但它似乎不起作用。

请帮助!!!

1 个答案:

答案 0 :(得分:14)

你看到的第二个解决方案看起来是正确的。但是,要清楚你想要完成什么。如果x和y是要在遍历期间找到要忽略的顶点之间的最短路径,如果它具有属性名称:“ignored”,那么查询是:

x.both.filter{it.name!="ignored"}.loop(2){!it.object.equals(y)}.paths>>1

如果要筛选的“给定顶点列表”实际上是一个列表,则遍历描述如下:

list = [ ... ] // construct some list
x.both.except(list).loop(2){!it.object.equals(y)}.paths>>1

此外,我倾向于使用范围过滤器只是为了安全,因为如果你忘记了>> 1,它会进入无限循环:)

x.both.except(list).loop(2){!it.object.equals(y)}[1].paths>>1

此外,如果可能没有路径,那么为了避免无限长的搜索,您可以执行循环限制(例如,不超过4个步骤):

x.both.except(list).loop(2){!it.object.equals(y) & it.loop < 5}.filter{it.object.equals(y)}.paths>>1

请注意为什么需要在路径之前的最后一个过滤步骤。循环被打破有两个原因。因此,当你突破循环时,你可能不会处于y(相反,你因为it.loops&lt; 5而中断了循环。)

这是您使用Gremlin分发的Grateful Dead图表实现的解决方案。首先设置一些代码,我们加载图形并定义两个顶点x和y:

gremlin> g = new TinkerGraph()
==>tinkergraph[vertices:0 edges:0]
gremlin> g.loadGraphML('data/graph-example-2.xml')
==>null
gremlin> x = g.v(89) 
==>v[89]
gremlin> y = g.v(100) 
==>v[100]
gremlin> x.name
==>DARK STAR
gremlin> y.name
==>BROWN EYED WOMEN

现在你的遍历。请注意,没有名称:“ignored”属性,因此我改变它以考虑沿着路径的每首歌曲的演奏次数。因此,歌曲的最短路径一共播放超过10次:

gremlin> x.both.filter{it.performances > 10}.loop(2){!it.object.equals(y)}.paths>>1
==>v[89]
==>v[26]
==>v[100]

如果您使用Gremlin 1.2+,那么您可以使用路径闭包来提供这些顶点的名称(例如),而不仅仅是原始顶点对象:

gremlin> x.both.filter{it.performances > 10}.loop(2){!it.object.equals(y)}.paths{it.name}>>1
==>DARK STAR
==>PROMISED LAND
==>BROWN EYED WOMEN

我希望有所帮助。

祝你好运! 马尔科。