0

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.

 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.

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!

Adam
  • 1,202
  • 11
  • 25
  • Any comments for this idea ? You can apply dfs algo and store index start and end time as range indexes. Then do topological sorting by normal search queries. – Vinit Siriah Aug 16 '22 at 09:54

2 Answers2

0

I found How to check equality with nodes from an earlier part of query in Gremlin?

and it seems like you use "as" with the same key as the previous "as" and if they match its considered equal.

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'

 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.

Adam
  • 1,202
  • 11
  • 25
0

You can try this gremlin query

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.

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. To fix this If you are doing this on jvm do use lamda/groovy closures


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

Vinit Siriah
  • 327
  • 3
  • 12
  • You can try this query quickly here https://gremlify.com/a2nm1q2nuq/4 – Vinit Siriah Aug 13 '22 at 22:33
  • I tend to never recommend use of closures as a lot of graph stores do not support the injection of arbitrary code into queries. – Kelvin Lawrence Aug 15 '22 at 14:03
  • Yes, that's there I just wrote that code to give a idea to designer on how they can innovate to add custom dsl if they have that option with like they can do with janusgraph, hugegraph, other tinkepop supported self hosted dbs. – Vinit Siriah Aug 16 '22 at 02:23
  • @KelvinLawrence do you have any ideas for aggregate alterative that can work per iteration basis ? just like fold unfold group under local ? – Vinit Siriah Aug 16 '22 at 02:39