Gremlin graph traversal that uses previous edge property value to filter later edges
Asked Answered
I

1

5

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?

Interne answered 20/10, 2016 at 22:18 Comment(0)
S
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]
Sympathy answered 21/10, 2016 at 7:24 Comment(4)
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 :(Compressibility
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.Sympathy
how about filter by 'secondEdge' - 'firstEdge' > 0.2 not just eq but with some simple arithmetic?Dehiscence
@jiamo: That should be possible with the math() step. Please create a new question if you need help with that.Sympathy

© 2022 - 2024 — McMap. All rights reserved.