【问题标题】:Gremlin continue traversal only if 2 vertices are not the sameGremlin 仅在 2 个顶点不相同时才继续遍历
【发布时间】:2022-08-14 06:24:18
【问题描述】:
我有一个查询,它查看 2 个不同的顶点,如果它们不都通过 \"contains\" 边的路径滚动到同一个根祖先,我想停止遍历。
g.V(\'node1\')
.until(hasLabel(\'root\')).repeat(in(\'contains\')).as(\'node1Root\')
.V(\'node2\')
.until(hasLabel(\'root\')).repeat(in(\'contains\')).as(\'node2Root\')
//FILTER|WHERE clause
在继续遍历之前,我想确认 node1Root 和 node2root 是同一个顶点,但对于我来说,我无法弄清楚如何做到这一点。
我尝试了以下方法:
g.V(\'node1\')
.until(hasLabel(\'root\')).repeat(in(\'contains\')).as(\'node1Root\')
.V(\'node2\')
.until(hasLabel(\'root\')).repeat(in(\'contains\')).as(\'node2Root\')
//.where(\'node1Root\', P.eq(\'node2Root\')
//.where(select(\"node1Root\").is(P.eq(\"node2Root\")))
//.where(select(\"node1Root\").is(\"node2Root\"))
有趣的是下面的查询做努力进行适当的过滤。
g.V(\'node1\').as(\'1\')
.V(\'node2\').as(\'2\')
.where(\'1\', P.eq(\'2\'))
我不确定直到/重复是否有问题,或者我只是在做一些公然错误的事情。任何帮助将非常感激。
谢谢!
标签:
gremlin
tinkerpop
amazon-neptune
【解决方案1】:
我找到了How to check equality with nodes from an earlier part of query in Gremlin?
并且您似乎使用“as”与之前的“as”具有相同的键,并且它们是否匹配其认为相等。
所以这是赢家(我认为):
g.V('node1')
.until(hasLabel('root')).repeat(in('contains')).as('node1Root')
.V('node2')
.until(hasLabel('root')).repeat(in('contains')).as('node2Root')
.where(select('node1Root').as('node2Root')
//.not(select('node1Root').as('node2Root')) //OR this to determine they aren't the same
//continue traversal
我还发现我最初的问题是 .until().repeat() 步骤可以返回一个 LIST,但在我的情况下,我知道我的图形模型将始终返回一个“根”,因此为了使其工作,我可以使用“展开”
g.V('node1')
.until(hasLabel('root')).repeat(in('contains')).unfold().as('node1Root')
.V('node2')
.until(hasLabel('root')).repeat(in('contains')).unfold().as('node2Root')
.where('node1Root', P.eq('node2Root')
我想我会选择第二种解决方案,因为我对此更有信心,除非我听到其他情况。
【解决方案2】:
你可以试试这个 gremlin 查询
g.V(node1-id)
.map(until(hasLabel('root')).repeat(in().aggregate('x')).cap('x')).as("array")
.V(node2-id)
.until(
as("i").select("array").unfold().as("j")
.where("i", eq("j"))
).repeat(in())
在这里,我们将从 node1 到根的路径中的所有顶点放入一个数组中,其次我们正在检查数组中是否存在节点。
此查询只能与只有一次迭代的遍历一起使用,因为aggregate 步骤收集到一个全局变量以进行遍历,这意味着每次迭代它都是相同的数组。解决这个问题如果你在 jvm 上这样做,请使用 lamda/groovy 闭包
g.V(node-start-id-1,node-start-id-2)
.map(
{ x->
var v = x.get()
var g = getGraph().get().traversal();
g.V(v.id())until(hasLabel('root')).repeat(in().aggregate('x')).cap('x')).next()
}
)
.as("array")
.V(node2-id)
.until(
as("i").select("array").unfold().as("j")
.where("i", eq("j"))
).repeat(in())