我需要使用 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
但它似乎不起作用。
请帮忙!!!
您拥有的第二个解决方案看起来是正确的。但是,要清楚您要完成的工作。如果 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 < 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
现在你的遍历。请注意,没有 name:"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
我希望这会有所帮助。
祝你好运!马尔科。