What next() means in TinkerPop
Asked Answered
C

1

11

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.

Chlorinate answered 1/12, 2015 at 9:22 Comment(0)
P
19

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
Poleax answered 1/12, 2015 at 11:29 Comment(2)
Every gremlin snippets is excerpted from TinkerPop3 Documentation So, "Why do you need to call next() in this case?" => the manual called next() ;)Chlorinate
Would you please answer this question? I really appreciate it if you can.Chlorinate

© 2022 - 2024 — McMap. All rights reserved.