0

I am trying to implement a gremlin query to for getting all vertex on same path based on property value. My graph looks like this. The label on graph is showing

  • name property and id for vertex
  • pathname property and id for edge

showing sample gremlin graph

Now the thing I want to achieve is when graph start from c and goes to e. I want to traverse with the starting edge property (any property would work in this case I have pathname property) and trace it's path up to e. To find path from c to e I am using.

g.V().has('name', 'c')
    .repeat(
        out()
    )
    .until(__.has('name', 'e'))
    .path()

But as you know this will give me two result for the path c->c1->c21->e (one with edge b1[c1] -> b1[c21] -> b1[e] another with edge from b1[c1] -> pb1[c21] -> b1[e]) But I want to get only one path as b1 is the only edge that start from c and goes all the way to e.

So the expected output for all the path query would be these path and total count would be 4.

//edge propertyname => path[vertex] -> path[vertex]
b1 => b1[c1] -> b1[c21] -> b1[e]
a1 => a1[d] -> a1[e]
d1 => d1[c3] -> d1[e]
c1 => c1[c2] -> c1[c31] -> c1[e]

Sample graph url https://gremlify.com/wij8933eelj

EDIT: there is a similar question here which is similar in nature but it doesnot resolve it in my case Gremlin simple path query, to get path based on first edge encountered property

Now for the case in which that does not work

Let's add an broken edge
c->d (pathname: r1) 
c21->e (pathname: r1)
Now the path returned for c->c1->c21->e becomes
b1->b1->b1 //within expectation
b1->b1->r1 //breaks here we only want edge with same pathname
Rajesh Paudel
  • 1,117
  • 8
  • 19
  • 1
    This sounds very similar to a question I answered here https://stackoverflow.com/questions/73036082/gremlin-simple-path-query-to-get-path-based-on-first-edge-encountered-property – Kelvin Lawrence Aug 21 '22 at 11:44
  • @KelvinLawrence totally forgot about cardinality. It tried to breakdown when implementing on my real graph. Which is quite complex. But it does work if it does not have the above case. – Rajesh Paudel Aug 21 '22 at 14:57
  • If you can add the `addE` and `addV` steps that create a sample graph to the question it will help give a tested answer. Based on comments and the question above, I still think the answer to the other question still applies here unless I am missing some nuance. – Kelvin Lawrence Aug 21 '22 at 17:02
  • 1
    I took the graph from Gremlify and added the additional edges. Until the question is re-opened I cannot post those steps here as a nicely formatted answer, but this query works `g.V().has('name','c').as('v1'). outE().values('pathname').as('n'). select('v1').as('start'). repeat( outE().where(eq('n')).by('pathname').by().inV()). until(has('name','e')). path().from('start'). by('name'). by('pathname')` – Kelvin Lawrence Aug 21 '22 at 18:28
  • Now that the question is re-opened I added an answer. – Kelvin Lawrence Aug 22 '22 at 18:53

1 Answers1

1

I took the graph from Gremlify and pretty printed it. So we start with:

g.addV('vertex').as('1').property(single, 'name', 'a').
  addV('vertex').as('2').property(single, 'name', 'b').
  addV('vertex').as('3').property(single, 'name', 'c').
  addV('vertex').as('4').property(single, 'name', 'd').
  addV('vertex').as('5').property(single, 'name', 'e').
  addV('vertex').as('6').property(single, 'name', 'f').
  addV('vertex').as('7').property(single, 'name', 'c1').
  addV('vertex').as('8').property(single, 'name', 'c2').
  addV('vertex').as('9').property(single, 'name', 'c3').
  addV('vertex').as('10').property(single, 'name', 'c21').
  addV('vertex').as('11').property(single, 'name', 'c31').
  addE('edge').from('1').to('2').property('pathname', 'a1').
  addE('edge').from('2').to('3').property('pathname', 'a1').
  addE('edge').from('3').to('7').property('pathname', 'b1').
  addE('edge').from('3').to('8').property('pathname', 'c1').
  addE('edge').from('3').to('9').property('pathname', 'd1').
  addE('edge').from('3').to('4').property('pathname', 'a1').
  addE('edge').from('3').to('4').property('pathname', 'pa2').
  addE('edge').from('4').to('5').property('pathname', 'a1').
  addE('edge').from('5').to('6').property('pathname', 'a1').
  addE('edge').from('7').to('10').property('pathname', 'b1').
  addE('edge').from('7').to('10').property('pathname', 'pb1').
  addE('edge').from('8').to('11').property('pathname', 'c1').
  addE('edge').from('8').to('11').property('pathname', 'pc1').
  addE('edge').from('9').to('5').property('pathname', 'd1').
  addE('edge').from('10').to('5').property('pathname', 'b1').
  addE('edge').from('11').to('5').property('pathname', 'c1')  

I then added the extra edges you mentioned in the comments using:

g.V().has('name','c').as('c').
  V().has('name','d').as('d').
  V().has('name','c21').as('c21').
  V().has('name','e').as('e').
  addE('edge').from('c').to('d').property('pathname','r1').
  addE('edge').from('c21').to('e').property('pathname','r1')

This gives us the following graph (rendered using graph-notebook):

example graph

The following query will only follow paths using properties found on the initial edges starting from c

g.V().has('name','c').as('v1').
  outE().values('pathname').as('n').
  select('v1').as('start').
  repeat(
    outE().where(eq('n')).by('pathname').by().inV()).
  until(has('name','e')).
  path().from('start').
    by('name').
    by('pathname')

and we only get back paths where each edge has the same pathname

1   path[c, a1, d, a1, e]
2   path[c, b1, c1, b1, c21, b1, e]
3   path[c, c1, c2, c1, c31, c1, e]
4   path[c, d1, c3, d1, e]
Kelvin Lawrence
  • 14,674
  • 2
  • 16
  • 38