Tinkerpop3 Reusing Traversal

1,387 views
Skip to first unread message

Flavio Cordova

unread,
Oct 10, 2015, 10:54:33 AM10/10/15
to Gremlin-users
Consider a situation where I've got to gather some statistics about some vertices in my graph, like that:

Double minutesSpent = g.V()
 
.has("type", "Epic").in()
 
.has("type", P.without("Bug", "Test Cycle"))
 
.until(__.in("TASK_OF").count().is(0)).repeat(__.inE("TASK_OF")
 
.outV())
 
.values("timeSpent")
 
.sum().next();

Long issuesWorked = g.V()
 
.has("type", "Epic").in()
 
.has("type", P.without("Bug", "Test Cycle"))
 
.until(__.in("TASK_OF").count().is(0)).repeat(__.inE("TASK_OF")
 
.outV())
 
.count();

Long peopleInvolved = g.V()
 
.has("type", "Epic").in()
 
.has("type", P.without("Bug", "Test Cycle"))
 
.until(__.in("TASK_OF").count().is(0)).repeat(__.inE("TASK_OF")
 
.outV())
 
.out()
 
.count();


Notice that part of the traversal code that selects the nodes is always the same, what seems really error-prone.

I've tried to isolate that code in a separated GraphTraversal:

GraphTraversal<Vertex,Vertex> baseQuery = g.V()
 
.has("type", "Epic").in()
 
.has("type", P.without("Bug", "Test Cycle"))
 
.until(__.in("TASK_OF").count().is(0)).repeat(__.inE("TASK_OF")
 
.outV());

Double minutesSpent = baseQuery.values("timeSpent").sum().next();
Long issuesWorked = baseQuery.count();
Long peopleInvolved = baeQuery.out().count();


The problem of this approach is that I can't reuse baseQuery because "The traversal strategies are complete and the traversal can no longer be modulated".

I've also thought about creating a subgraph and then work with it, but the problem is that "g" is already a subgraph and apparently I can't create a subgraph from another, narrowing the view.

Is there any different approach that I could use in this case ?


Daniel Kuppitz

unread,
Oct 10, 2015, 11:03:14 AM10/10/15
to gremli...@googlegroups.com
Hi Flavio,

clone() will be your friend:

gremlin> baseQuery = g.V().hasLabel("person"); q1 = baseQuery.clone().out("knows").path().by("name"); q2 = baseQuery.clone().out("created").path().by("name"); []
gremlin> q1
==>[marko, vadas]
==>[marko, josh]
gremlin> q2
==>[marko, lop]
==>[josh, ripple]
==>[josh, lop]
==>[peter, lop]


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/c703e0c7-7dc0-4f65-852d-319292991c32%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Flavio Cordova

unread,
Oct 14, 2015, 9:43:31 PM10/14/15
to Gremlin-users
I've tried Traversal and GraphTraversal and none of them have a clone method.

Am I missing something ? Wrong version, maybe ?
(I'm using 3.01)

Daniel Kuppitz

unread,
Oct 14, 2015, 9:51:50 PM10/14/15
to gremli...@googlegroups.com

Flavio Cordova

unread,
Oct 15, 2015, 8:37:34 AM10/15/15
to Gremlin-users
Actually, implementing Cloneable only won't make the method public because it's protected on Object class and Cloneable is just a marker interface.

However looking the code I found out that Traversal has an inner interface called Admin and Traversal.Admin does expose the clone method, so the code bellow works just fine:

Traversal t = graph.traversal().V().has("type", "COMPONENT");
Traversal newT = t.asAdmin().clone();

System.out.println("Count1: " + t.count().next());

System.out.println("Count2: " + newT.count().next());


Reply all
Reply to author
Forward
0 new messages