E(...) step mid-query

196 views
Skip to first unread message

Daniel C. Weber

unread,
Apr 18, 2020, 6:31:35 AM4/18/20
to Gremlin-users
Hello,

a recent issue on my project ExRam.Gremlinq (https://github.com/ExRam/ExRam.Gremlinq/issues/62) brought my attention to the following:

I learned that you can't query all edges mid-query, that is, neither "GraphTraversal" nor "__" define an "E(...)" method while there is a V(...) method. Now the OPs workaround was to reuse "g" in the middle of the query, like in "g.V().coalesce(g.E(), __.addE(...))" (simplified!!). I argued that it's invalid gremlin, but it seems it's legal, plus it works. I understand that your're pretty much running two queries now, but the workaround still seems odd to me. Is it legal, and moreover....how would you even represent this in bytecode?

Regards,
Daniel


Kelvin Lawrence

unread,
Apr 18, 2020, 3:10:06 PM4/18/20
to Gremlin-users
You can do V().outE() mid traversal

Cheers
Kelvin

Kelvin Lawrence

unread,
Apr 18, 2020, 3:14:26 PM4/18/20
to Gremlin-users
Sorry hit send too soon. Meant to add you can use the Gremlin console to inspect Bytecode. For example

gremlin> :bc from g.V().coalesce(g.E(),constant(1))
==>{"@type":"g:Bytecode","@value":{"step":[["V"],["coalesce",{"@type":"g:Bytecode","@value":{"ste
p"
:[["E"]]}},{"@type":"g:Bytecode","@value":{"step":[["constant",{"@type":"g:Int32","@value":1}]]
}}]]}}    

            
Cheers
Kelvin

Daniel C. Weber

unread,
Apr 19, 2020, 3:59:16 AM4/19/20
to Gremlin-users
Thanks Kelvin,

The bytecode doesn't indicate that there's a fresh start from "g" in the middle. Moreover, e.g. "g.V().coalesce(g.E(), g.addE('l'))" and "g.V().coalesce(g.E(), __.addE('l'))" have the same bytecode. I didn't send the bytecode you posted to a Gremlin Server yet, will do so later in the day. But my guess is that it wouldn't take it because it interprets the query as equivalent to "g.V().coalesce(__.E(),constant(1))".

Daniel C. Weber

unread,
Apr 19, 2020, 8:58:36 AM4/19/20
to Gremlin-users
It is indeed what happens: When sending ":bc from g.V().coalesce(g.E(),constant(1))" to the server, we get an exception (see below). I conclude that it's - at least in this case - an anti pattern to use "g" mid-query. So what might be the rationale for omitting "E" on DefaultGraphTraversal? There is a workaround that would only work for groovy, and another that might have increased execution costs (tried V().outE() in CosmosDB, the execution is slightly more expensive than plain E).
 

java.lang.IllegalStateException: Could not locate method: DefaultGraphTraversal.E()
at org.apache.tinkerpop.gremlin.jsr223.JavaTranslator.translateObject(JavaTranslator.java:115)
at org.apache.tinkerpop.gremlin.jsr223.JavaTranslator.invokeMethod(JavaTranslator.java:196)
at org.apache.tinkerpop.gremlin.jsr223.JavaTranslator.translate(JavaTranslator.java:87)
at org.apache.tinkerpop.gremlin.server.op.traversal.TraversalOpProcessor.iterateBytecodeTraversal(TraversalOpPr
ocessor.java:384)

Stephen Mallette

unread,
Apr 20, 2020, 8:49:34 AM4/20/20
to gremli...@googlegroups.com
So what might be the rationale for omitting "E" on DefaultGraphTraversal? 

I don't remember why we don't have mid-traversal E().  It might have something to do with not promoting E() any more as start step. We've had discussion on that before whether it is necessary at all. Despite my distaste for it, it seemed like some folks were into it and had use cases for it. It still seems better if we always started with vertices and even g.E(123) being better stated as g.V().outE().hasId(123) where providers who can compile to a edge id lookup would.   

tried V().outE() in CosmosDB, the execution is slightly more expensive than plain E)  

I'd wonder if any provider has optimized for  g.V().outE().hasId(123) at this point. TinkerGraph probably doesn't even do that. My guess is that there hasn't be necessity for it since E() existed as a start step. Of course, that puts using that as a mid-traversal workaround at odds with the idea of not having a fully fledged mid-traversal E().

> an anti pattern to use "g" mid-query  

I dislike that use of "g" mid-query. CosmosDB likes to put that in that in their documentation and blog posts. It's unfortunate that it even works, but the Java interface hierarchy allows it unfortunately. I'd like to make this more than just convention:


The GraphTraversalSource implies the start of a new traversal and shouldn't be confused with spawning child traversals anonymously. 


--
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/4643540a-bd05-45e9-be02-c2fe5011732e%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages