Consecutive repeat-times-emit-dedup steps inside an and/or step

282 views
Skip to first unread message

Eric Steele

unread,
Mar 2, 2017, 8:25:13 AM3/2/17
to Gremlin-users
Hi all,

I recently joined this group. I'm loving Gremlin so far, but I'm having trouble explaining some results I'm seeing. Any help you can provide would be much appreciated!

Implementation
I am using DataStax Graph 5.0.2

The Setup
My graph includes 7 vertices. Each vertex has a property named "value" that is an uppercase letter: A, B, C, D, E, F, and G. This graph is arranged as follows:

A             F
╲ ╱
C -> D -> E
╱ ╲
B G

From left to right, all edges shown above are outgoing edges (A and B point to C; C points to D; D points to E; E points to F and G).

Given the following query:

g.V().hasLabel('label').or(
  __.in('edge').out('edge').has('value', 'G'),                        // traversal #1
__.in('edge').in('edge').out('edge').has('value', 'G'), // traversal #2
  __.in('edge').out('edge').out('edge').has('value', 'G'),            // traversal #3
  __.in('edge').in('edge').out('edge').out('edge').has('value', 'G')  // traversal #4
)

I get back vertices E, F, and G, which makes sense to me. Traversals #1 and #4 both yield F and G; traversal #3 yields E; traversal #2 yields nothing

I figured that I could also represent the query above as follows:

g.V().hasLabel('label').or(
  __.repeat(__.in('edge')).times(2).emit().dedup().out().has('value', 'G'),       // traversal #5
  __.repeat(__.in('edge')).times(2).emit().dedup().out().out().has('value', 'G')  // traversal #6
)

As I expected, this query also returns vertices E, F, and G.

I then tried to see if the following query could achieve the same result:

g.V().hasLabel('label').or(
  __.repeat(__.in('edge')).times(2).emit().dedup().repeat(out('edge')).times(2).emit().dedup().has('value', 'G') // traversal #7
)

This, however, returns vertices A, C, E, F and G, which does not make sense to me. Can anyone explain why this query returns vertices A and C?

My expectation was that the final ".has('value', 'G')" clause would filter out A and C because both are at least 3 hops away from G, and the "repeat(out('edge'))" is only "times(2)".

Furthermore, when I execute the *inverse* of this query (i.e. reverse edge directions and target vertex A):

g.V().hasLabel('label').or(
  __.repeat(out('edge')).times(2).emit().dedup().repeat(__.in('edge')).times(2).emit().dedup().has('value', 'A') // traversal #8
)

I am getting back vertices A, B, and C, which I would expected. There seems to be a discrepancy here, given that this query is the same as query #3, just inverted.

I'd be eternally grateful if someone could shed some light on this situation.

Best Regards,
Eric Steele

Eric Steele

unread,
Mar 2, 2017, 1:47:39 PM3/2/17
to Gremlin-users
For anyone that wants to test this out for themselves, here you can run the following to get the graph setup:

Vertex A = graph.addVertex(label, 'label', 'value', 'A');
Vertex B = graph.addVertex(label, 'label', 'value', 'B');
Vertex C = graph.addVertex(label, 'label', 'value', 'C');
Vertex D = graph.addVertex(label, 'label', 'value', 'D');
Vertex E = graph.addVertex(label, 'label', 'value', 'E');
Vertex F = graph.addVertex(label, 'label', 'value', 'F');
Vertex G = graph.addVertex(label, 'label', 'value', 'G');
A.addEdge('edge', C);
B.addEdge('edge', C);
C.addEdge('edge', D);
D.addEdge('edge', E);
E.addEdge('edge', F);
E.addEdge('edge', G);

Eric Steele

unread,
Mar 2, 2017, 2:18:10 PM3/2/17
to Gremlin-users
If my understanding of Gremlin is correct, traversal #7 should be more-or-less equivalent to the following:

g.V().hasLabel('label').has('value', 'G').repeat(__.in('edge')).times(2).emit().dedup().repeat(out('edge')).times(2).emit().dedup()

Which returns E, F, and G as expected. Again, this makes me wonder why #7 returns A, E, F, and G.

Eric Steele

unread,
Mar 2, 2017, 2:57:42 PM3/2/17
to Gremlin-users
One correction to make: Traversals #1 yields only G, #4 yields both F and G; traversal #3 yields E; traversal #2 yields nothing

g.V().hasLabel('label').or(
  __.in('edge').out('edge').has('value', 'G'),                        // traversal #1
__.in('edge').in('edge').out('edge').has('value', 'G'), // traversal #2
  __.in('edge').out('edge').out('edge').has('value', 'G'),            // traversal #3
  __.in('edge').in('edge').out('edge').out('edge').has('value', 'G')  // traversal #4
)

HadoopMarc

unread,
Mar 2, 2017, 4:12:21 PM3/2/17
to Gremlin-users
Hi Eric,

Did not try to understand, but just put it in my v3.2.3 gremlin console:

gremlin> g.V().hasLabel('label').or(__.repeat(__.in('edge')).times(2).emit().dedup().repeat(out('edge')).times(2).emit().dedup().has('value', 'G')).valueMap()
==>[value:[E]]
==>[value:[F]]
==>[value:[G]]
gremlin
> g.V().hasLabel('label').valueMap()
==>[value:[A]]
==>[value:[B]]
==>[value:[C]]
==>[value:[D]]
==>[value:[E]]
==>[value:[F]]
==>[value:[G]]


So, I get E,F, G for traversal 7, as you wanted.

Hope this points you in the right direction!

Marc

Op donderdag 2 maart 2017 20:57:42 UTC+1 schreef Eric Steele:

Daniel Kuppitz

unread,
Mar 2, 2017, 8:44:28 PM3/2/17
to gremli...@googlegroups.com
Same here, nothing unexpected. Just wanted to add a traversal, that helps to debug the result:

gremlin> g.withPath().V().hasLabel('label').or(
           repeat(__.in('edge')).times(2).emit().dedup().repeat(out('edge')).times(2).emit().dedup().has('value', 'G').
           sideEffect {println it.path().objects()*.value("value")}

         ).values()
[E, D, E, G]
==>E
[F, E, G]
==>F
[G, E, G]
==>G

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-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/b047853b-664b-401d-909c-3efe0c07b1de%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Eric Steele

unread,
Mar 2, 2017, 10:02:02 PM3/2/17
to Gremlin-users
Thank you both for giving it a try. At the very least, I think this shows that my reasoning was correct. 

Perhaps there's a bug in my installation of DSE Graph. I'll try updating and see if the issue persists.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-user...@googlegroups.com.

Eric Steele

unread,
Apr 3, 2017, 8:17:06 PM4/3/17
to Gremlin-users
Hey, sorry to bother you again, but when I run the Gremlin you posted:

gremlin> Gremlin.version

==>3.2.4-20170124-6a0001ac

gremlin> g.withPath().V().hasLabel('label').or(

gremlin>           repeat(__.in('edge')).times(2).emit().dedup().repeat(out('edge')).times(2).emit().dedup().has('value', 'G').

gremlin>           sideEffect {println it.path().objects()*.value("value")}

gremlin>          ).values()

==>E

==>G

==>A

==>F


I'm not seeing the full path printed as you do. It just shows the vertices. Is there something more I need to do?



On Thursday, March 2, 2017 at 5:44:28 PM UTC-8, Daniel Kuppitz wrote:
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-user...@googlegroups.com.

Daniel Kuppitz

unread,
Apr 3, 2017, 8:29:00 PM4/3/17
to gremli...@googlegroups.com
If you're using Gremlin Server, then you won't see the printed paths in your local console. You should be able to find it in the server logs though.

Cheers,
Daniel


To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/9fd5df39-9dcc-4487-ae69-01a594fae72c%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages