Traversal Based on path minus 2 vertex seen

223 views
Skip to first unread message

Antriksh Shah

unread,
Jun 18, 2019, 3:58:22 AM6/18/19
to Gremlin-users
Hey all,

I want to traverse using a tricky condition.

Condition:
If in a traversal path, two vertex separated by a distance of1 have same vertex type then that path should not be considered.
OR
While traversing if a vertex is encountered whose path-2 vertex is of the same type, stop the traversal there.

I do not want to apply a filter conditions once all the paths are traversed. I want to perform this filtering while the traversal is happening.

Sample Graph:
l1=graph.addVertex("type","l","id","l1")
p1=graph.addVertex("type","p","id","p1")
l2=graph.addVertex("type","l","id","l2")
v1=graph.addVertex("type","v","id","v1")
l3=graph.addVertex("type","l","id","l3")

l1.addEdge("edge",p1)
p1.addEdge("edge",l2)
p1.addEdge("edge",v1)
v1.addEdge("edge",l3)


Output:
If start node is l1 then output is (p1,v1,v3) 
If start node is p1 then output is (l1,l2,v1,l3)
If start node is l2 then output is (p1,v1,l3)
If start node is v1 then output is (p1,l1,l2,l3)
If start node is l3 then output is (v1,p1,l1,l2)
______________________________________________________________________________________________________________________

I am stuck at trying to figure out the syntax for the n-2 element in the path. Moreover can I have an if else condition inside my traversal?

Something like

g.V().repeat( obtain path-2 if exists && if type of path-2 vertex != current vertex.path then both())

Any insights on how I can perform this kind of traversal, greatly appreciated.

Thanks and Regards,
Antriksh Shah



Antriksh Shah

unread,
Jun 18, 2019, 4:26:49 AM6/18/19
to Gremlin-users
In the above post OR I wanted to mean "in other words". It is not a logical OR operator. Sorry if it was ambiguous. 

Antriksh Shah

unread,
Jun 18, 2019, 6:09:56 AM6/18/19
to Gremlin-users
I was playing around and I got so far:

With tail command I can access elements backwards from a path. I am not sure why I need to perform unfold() and why I cannot access elements from Path directly.



g.V().
has("id","l1").
emit().
repeat(
both().as("a").where(
path().by("tid").unfold().tail(1).values("type") //?? should not be equal to values stored in a.type
)
).times(5)

Assuming I am on intermediate step x, repeat on my next vertices provided they satisfy the where clause which says get my paths last vertex and if its property not equal to my next vertices property.

But I am unable to find the correct way to implement this. :(

Any help on this deeply appreciated.

Antriksh Shah

unread,
Jun 18, 2019, 9:51:54 AM6/18/19
to Gremlin-users
I was trying one more query which I believe is more succinct. I am not sure how to implement the 4th line. Compare current value with value observed 2 stages back in the path. 

gremlin> g.V().
......1>     has("id","l1").both().
......2>     emit().
......3>     repeat(both()).
......4>     until(values("type").eq(path().unfold().tail(2).limit(1).values("type")))

No signature of method: org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal.eq() is applicable for argument types: (org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal) values: [[PathStep, UnfoldStep, TailGlobalStep(2), RangeGlobalStep(0,1), PropertiesStep([type],value)]]
Possible solutions: by(groovy.lang.Closure), is(java.lang.Object), next(), any(), grep(), min()

Antriksh Shah

unread,
Jun 18, 2019, 1:29:18 PM6/18/19
to Gremlin-users
Is there any way we can access path of a vertex in filter clause?

g.V().has("id","l1").out().emit().
repeat(
both().filter{it.get().values("type").next()!=it.get().path().unfold().tail(2).limit(1).values("type").next()}
).times(3).valueMap()

It throws this error:
No signature of method: org.janusgraph.graphdb.vertices.CacheVertex.path() is applicable for argument types: () values: []

Fabio Lorenzi

unread,
Jun 19, 2019, 5:08:15 AM6/19/19
to Gremlin-users
>  I do not want to apply a filter conditions once all the paths are traversed. I want to perform this filtering while the traversal is happening.

I do not know of a way to stop a repeat and discard a path so it might not be possible altogether. 
If it is possible I woud go with something like like a combination of repeat(choose()).
Give choose() step a look :D

Antriksh Shah

unread,
Jun 19, 2019, 5:32:12 AM6/19/19
to Gremlin-users
I have tried all sorts of combinations including choose! The struggle I am facing is with obtaining path-2 and the current vertex and comparing them on the fly. I guess I am missing on some syntax error.

I was trying a few things along these lines but did not work:

g.V(4240).both().repeat(
__.as("v1").path().store("a2").select("v1").unfold().tail(1).
choose(
__.as("v1").values("type").is(neq(select("a2").unfold().tail(2).limit(1).values("type"))), 
both(),
g.V(0)//I thought this might work to discard a traversal
)
).times(2).path() 

Daniel Kuppitz

unread,
Jun 20, 2019, 2:47:17 PM6/20/19
to gremli...@googlegroups.com
Using tail() was a step in the right direction, but then, going forward, you totally screwed up the filters :).

Your query would be:

g.V(startV).
  repeat(both().
         not(path().
             and(count(local).is(gte(3)),
                 tail(local, 3).as('last3').
                 tail(local, 1).as('last').
                 select('last3').limit(local, 1).
                 where(eq('last')).
                   by('type')))).
    emit().
  path().
    by('id').
  skip(local, 1).
  unfold().dedup().fold()

Running it on your sample graph:

gremlin> query = { startV ->
......1>   g.V(startV).
......2>     repeat(both().
......3>            not(path().
......4>                and(count(local).is(gte(3)),
......5>                    tail(local, 3).as('last3').
......6>                    tail(local, 1).as('last').
......7>                    select('last3').limit(local, 1).
......8>                    where(eq('last')).
......9>                      by('type')))).
.....10>       emit().
.....11>     path().
.....12>       by('id').
.....13>     skip(local, 1).
.....14>     unfold().dedup().fold()
.....15> }
==>groovysh_evaluate$_run_closure1@57e4b86c

gremlin> // If start node is l1 then output is (p1,v1,v3)
gremlin> query(l1)
==>[p1,v1,l3]

gremlin> // If start node is p1 then output is (l1,l2,v1,l3)
gremlin> query(p1)
==>[l2,v1,l1,l3]

gremlin> // If start node is l2 then output is (p1,v1,l3)
gremlin> query(l2)
==>[p1,v1,l3]

gremlin> // If start node is v1 then output is (p1,l1,l2,l3)
gremlin> query(v1)
==>[l3,p1,l2,l1]

gremlin> // If start node is l3 then output is (v1,p1,l1,l2)
gremlin> query(l3)
==>[v1,p1,l2,l1]

Cheers,
Daniel


--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/1e9f4eb1-1037-4c3f-a4cd-d1ebc8a42d66%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Daniel Kuppitz

unread,
Jun 20, 2019, 2:50:45 PM6/20/19
to gremli...@googlegroups.com
Actually, you don't need path() in the end. It's just:

g.V(startV).
  repeat(both().
         not(path().
             and(count(local).is(gte(3)),
                 tail(local, 3).as('last3').
                 tail(local, 1).as('last').
                 select('last3').limit(local, 1).
                 where(eq('last')).
                   by('type')))).
    emit().
  values('id').dedup().fold()

Cheers,
Daniel

Antriksh Shah

unread,
Jun 21, 2019, 12:16:16 AM6/21/19
to Gremlin-users
Brilliant! I believe you have heard it countless times in this group, yet, thank you!

First time seeing how to use not(), and() predicates. It makes filtering easier. So far I only knew where() or filter() or choose(), but these two are good ways to chain condition checking for multiple predicates.
Also I was really struggling to alias path() so that I can reuse multiple times. Didn't know we can use local in this way. 

Thanks again!

In the above query, I added simplePath() to avoid going into infinite loops.

g.V(startV).
  repeat(both().simplePath()
...

Reply all
Reply to author
Forward
0 new messages