简体   繁体   English

Gremlin 仅在 2 个顶点不相同时才继续遍历

[英]Gremlin continue traversal only if 2 vertices are not the same

I have a query which looks at 2 different vertices and I want to stop traversing if they don't both roll up to the same root ancestor via a path of "contains" edges.我有一个查询,它查看 2 个不同的顶点,如果它们不都通过“包含”边的路径滚动到同一个根祖先,我想停止遍历。

 g.V('node1')
  .until(hasLabel('root')).repeat(in('contains')).as('node1Root')
  .V('node2')
  .until(hasLabel('root')).repeat(in('contains')).as('node2Root')
  //FILTER|WHERE clause

I'd like to confirm that node1Root and node2root are the same vertex before continuing the traversal, but for the life of me I cannot figure out how to do this.在继续遍历之前,我想确认 node1Root 和 node2root 是同一个顶点,但是对于我来说,我无法弄清楚如何做到这一点。

I've tried the following:我尝试了以下方法:

 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"))

What's interesting is that the following query does work to filter appropriately.有趣的是,以下查询确实可以进行适当的过滤。

g.V('node1').as('1')
 .V('node2').as('2')
 .where('1', P.eq('2'))

I'm not sure if there's something up with the until/repeat that screws it up or if I'm just doing something blatantly wrong.我不确定直到/重复是否有什么问题导致它搞砸了,或者我只是在做一些公然错误的事情。 Any help would be much appreciated.任何帮助将非常感激。

Thanks!谢谢!

I found How to check equality with nodes from an earlier part of query in Gremlin?我发现如何检查 Gremlin 中早期查询部分的节点是否相等?

and it seems like you use "as" with the same key as the previous "as" and if they match its considered equal.并且您似乎使用“as”与之前的“as”具有相同的键,并且它们是否匹配其认为相等。

So here's the winner (I think):所以这是赢家(我认为):

 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

I also found that my original issue was that the.until().repeat() steps could return a LIST, but in my case I know that my graph model will always return a single 'root' so to make it work, I can use 'unfold'我还发现我最初的问题是 .until().repeat() 步骤可以返回一个 LIST,但在我的情况下,我知道我的图表 model 将始终返回一个“根”,所以为了让它工作,我可以使用“展开”

 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')

I think I'll be going with the second solution because I'm much more confident in it, unless I hear otherwise.我想我会采用第二种解决方案,因为我对此更有信心,除非我听到其他情况。

You can try this gremlin query你可以试试这个 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())

Here we are putting all the vertices in path to root from node1 in an array, and secondly we are checking existence of node in array.在这里,我们将从 node1 到根的路径中的所有顶点放入一个数组中,其次我们正在检查数组中是否存在节点。

this query can only work with traversal with only one iteration because aggregate step collect to a global variable to traversal that means it will be same array for every iteration.此查询只能与只有一次迭代的遍历一起使用,因为aggregate步骤收集到一个全局变量以进行遍历,这意味着每次迭代它将是相同的数组。 To fix this If you are doing this on jvm do use lamda/groovy closures解决此问题 如果您在 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())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM