Search code examples
gremlintinkerpop

Gremlin find shortest path and inspect each vertex along it for specific edge types


I'm learing Gremlin and trying to find a way to traverse from a given vertex to another along a path and "locating" each edge of a type and the associated node.

This is a basic representation of the graph I'm working with: enter image description here

What I'm trying to do is to find a way to traverse from a station vertex to another along travelsTo edges and if any announcedOn edges are encountered along the way then gather up all announcement vertecies along the path: enter image description here

In the example above I want to end up with two announcement elements in a list with their properties. If possible I'd also want to return the path taken to retrieve them as the final graph will have many different ways to get from station A to station B. Basically, I'd like to follow the path and find all announcement vertecies that are encountered.

I can relatively easily traverse the path using repeat() and .path() like this:

g.V()
    .has("station", "code", "ABC")
    .repeat(out("travelsTo").simplePath())
    .until(
      has("station", "code", "XYZ")
    ).path()

But I'm not sure how I can introduce the "gathering og announcement" requirement here. I guess I'm missing something basic about traversals. Any help would be greatly appreciated!

Edit for clarification:

Given a starting station vertex and an ending station vertex, I'd like to find a path from start -> end. For each vertex in this path I'd also like to find any announcement vertex associated with it through an incomming announcedOn edge. The result I hope to get is:

  • path: vertex -> edge -> vertex -> ... -> vertex
  • announcements[]

Solution

  • Not having sample data means that this is untested but I think the query will need to be along these lines:

    g.V().
      has("station", "code", "ABC").
      repeat(out("travelsTo").           
             sideEffect(in('announcedOn').store('announcements')).simplePath()).
      until(has("station", "code", "XYZ")).
      union(path().fold(),cap('announcements').dedup(local))       
    

    The only downside of this approach is that the 'announcements' are not tied to a given path.