Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What next() means in TinkerPop

I'm currently reading the TinkerPop3 Documentation

What I'm confused is that I can't find any explanation about next().

For example, w/ next() or w/o next() returns same vertext

gremlin> g.V().has('name', 'marko')
==>v[1]
gremlin> g.V().has('name', 'marko').next()
==>v[1]

but, the class names are different from each other.

gremlin> g.V().has('name', 'marko').getClass()
==>class org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal
gremlin> g.V().has('name', 'marko').next().getClass()
==>class org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertex

Without 'next()' an assigned variable has no value.

gremlin> marko = g.V().has('name', 'marko')
==>v[1]
gremlin> marko

Even, with clockWithResult() the outputs are completely different.

gremlin> clockWithResult(1){g.V().both().barrier().both().barrier().both().barrier().count().next()}
==>1.079524
==>72
gremlin> clockWithResult(1){g.V().both().barrier().both().barrier().both().barrier().count()}
==>0.11863599999999999
==>[GraphStep([],vertex), VertexStep(BOTH,vertex), NoOpBarrierStep(2147483647), VertexStep(BOTH,vertex), NoOpBarrierStep(2147483647), VertexStep(BOTH,vertex), NoOpBarrierStep(2147483647), CountGlobalStep]

or this example:

gremlin> g.V(1).out('knows').values('name').fold()
==>[vadas, josh]
gremlin> g.V(1).out('knows').values('name').fold().next()
==>vadas
==>josh

In the manual, there are many other examples which make me confusing.

I hope marko and his friends would help me.

like image 994
Jason Heo Avatar asked Dec 01 '15 09:12

Jason Heo


People also ask

What is Gremlin and TinkerPop?

Gremlin is the graph traversal language of Apache TinkerPop. Gremlin is a functional, data-flow language that enables users to succinctly express complex traversals on (or queries of) their application's property graph. Every Gremlin traversal is composed of a sequence of (potentially nested) steps.

How do you get edges in Gremlins?

Create an edge To create a new edge between two vertices, use the addEdge(v1, v2, label) method. The edge will be created with the label specified. In the example below two vertices are created and assigned to a variable (Gremlin is based on Groovy), then an edge is created between them.

What is Gremlin used for?

Gremlin is JanusGraph's query language used to retrieve data from and modify data in the graph. Gremlin is a path-oriented language which succinctly expresses complex graph traversals and mutation operations.


1 Answers

The short answer is that the Gremlin Console iterates results for you automatically.

x = g.V().has('name', 'marko')

In the above example, x will be a Traversal instance, which is a type of Iterator. When the console encounters an Iterator it automatically unrolls it so that you can see the results. In this case:

x = g.V().has('name', 'marko').next()

the addition of next() just says that you want to call Iterator.next() - in other words you want to get the first item out of the Iterator. So, in the above case, x will be a Vertex.

For this case:

gremlin> marko = g.V().has('name', 'marko')
==>v[1]
gremlin> marko

you now know that marko is an Iterator, so when you evaluate it on again, the console tries to iterate it. Of course, the console already iterated it on the previous line, so when it attempts to do so again, there is nothing additional to iterate. Here's an example that makes it more apparent as to what is going on:

gremlin> x = g.V();null
==>null
gremlin> x.next()
==>v[1]
gremlin> x.next()
==>v[2]
gremlin> x
==>v[3]
==>v[4]
==>v[5]
==>v[6]

Note the use of ;null on the first line which prevents the console from iterating x. Why? because my script returns null not the x.

It should now be clear as to what your example with clock is doing...the first line which calls next() is measuring the execution of the traversal and the second is measuring the execution of the Traversal construction. Why do you need to call next() in this case? Because the Traversal is inside of a closure - remember, the Console only iterates the return value of the function not every Iterator in your scripts.

Finally:

gremlin> g.V(1).out('knows').values('name').fold()
==>[vadas, josh]
gremlin> g.V(1).out('knows').values('name').fold().next()
==>vadas
==>josh

hopefully everything else I've discussed above allows you to see why the next() produces this behavior, but just in case, here's what the console is doing essentially:

gremlin> x = g.V(1).out('knows').values('name').fold();null
==>null
gremlin> y = x.next();null
==>null
gremlin> y
==>vadas
==>josh
like image 195
stephen mallette Avatar answered Oct 02 '22 15:10

stephen mallette