6

In a graph traversal I only want to consider edges that have a property that is equal to the property of one of the edges visited in a previous step in the traversal.

I found http://tinkerpop.apache.org/docs/current/recipes/#traversal-induced-values but this appears to only work for a single object, in my case I need the value to change as I traverse. For example starting at V1 that has the outbound edges (E1, E2, E3...) I want to traverse out E1 to V2 and then traverse along any edge from V2 where edge.property(x) == E1.property(x), and do the same for all edges out of V1 (E2, E3, ...)

I can't find any documentation that supports a way to do this in Gremlin, is it possible?

Chris Reeves
  • 61
  • 1
  • 3

1 Answers1

9

We can use the modern toy graph that ships with TinkerPop:

gremlin> graph = TinkerFactory.createModern()
==>tinkergraph[vertices:6 edges:6]
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]

This graph already contains 6 edges of which two have a weight of 1.0:

gremlin> g.E().valueMap()
==>[weight:0.5]
==>[weight:1.0]
==>[weight:0.4]
==>[weight:1.0]
==>[weight:0.4]
==>[weight:0.2]

We use one of these two edges with a weight of 1.0 to get the other edge with the same weight. By traversing the first of these two edges, we land at a vertex that has two outgoing edges:

gremlin> g.V(1).outE().has('weight',1.0).inV().outE()
==>e[10][4-created->5]
==>e[11][4-created->3]
gremlin> g.V(1).outE().has('weight',1.0).inV().outE().valueMap()
==>[weight:1.0]
==>[weight:0.4]

One of these edges is the other one with the weight of 1.0. So, we only have to filter these edges based on the weight of the first edge:

gremlin> g.V(1).outE().has('weight',1.0).
                as('firstEdge'). // save the first edge
                inV().outE().
                where(eq('firstEdge')). // compare with the first edge
                by('weight') // use only the 'weight' property for the equality check
==>e[10][4-created->5]
Florian Hockmann
  • 2,249
  • 9
  • 23
  • 1
    Is there any way to accomplish this without the match() step? Microsoft Azure's CosmosDB supports the gremlin query language, expect it can't handle the match() step yet :( – SnoopDougg Nov 14 '18 at 14:08
  • 1
    Thanks for asking about the `match()` step. While reading my answer again, I noticed that it isn't really necessary to use `match()` here. I edited my answer to solve the problem without using `match()` which makes it much more readable in my opinion. – Florian Hockmann Nov 21 '18 at 17:00