3

I have a graph that looks like this: graph

Using gremlin-scala, I'm trying to traverse from A and collect these tuples:

(A, Some(A1)), (B, None), (C, Some(A2))

So essentially I want to repeatedly take α out edges and optionally branch to β, collecting those outs. I am guessing I need to inject an empty "step" if there's no β edge but I haven't been able to figure out how to do that.

I'm also a bit confused about how to rewind after traversing β now that jump has been mysteriously removed (TP 3.1+)

So far I have something like:

graph.V("A").untilWithTraverser(t => t.get.outE(α).notExists()
    ).repeat(_.out(α).as(foo).out(β).as(bar)).select((foo,bar)).toList

But this doesn't rewind back to the main traversal and fails if any nodes on the "trunk" are missing a β out edge

Arkadiy Kukarkin
  • 2,153
  • 14
  • 24

2 Answers2

4

I can't provide a gremlin-scala solution, but it should be easy for you to convert the following Groovy example:

g.V("A").until(__.not(outE("alpha"))).
           repeat(out("alpha")).path().by(union(identity(), out("beta")).fold())

This will return:

[[A, A1], [B], [C, A2]]

IMO this is sufficient. However, if you need a consistent set of 2 entries, you could do something like this:

g.V("A").until(__.not(outE("alpha"))).repeat(out("alpha")).
  path().by(union(identity(), coalesce(out("beta"), constant("N/A"))).fold())

...which will then return:

[[A, A1], [B, N/A], [C, A2]]

Complete Session:

http://gremlinbin.com/bin/view/57133bdc8ee00

Daniel Kuppitz
  • 10,846
  • 1
  • 25
  • 34
1

This is my gremlin-scala solution, based on Daniel's answer.

val unionTraversal = __[(String, Vertex)].union(
  __[Vertex].identity.map("blob" -> _),
  __.out(Beta).map("beta" -> _)
).traversal

def pathTuplesToScalaTuples(path: Path) =
  path.objects.asScala.map(_.asInstanceOf[java.util.ArrayList[(String, Vertex)]].asScala.toList).toList

val pathO = graph.V("A")
    .until(_.not(_.out(Alpha)))
    .repeat(_.out(Alpha))
    .path.by(unionTraversal.fold).headOption
val tuples = pathO.map(pathTuplesToScalaTuples)

This, unfortunately, involves a couple of kludges to actually make the emitted vertices useful.

First, step labels get erased when passing an anonymous traversal into a union so you can't label your emitted sets with .as("blob") -- this is what the workaround with wrapping them in tuples with string labels is for.

Second, gremlin-scala doesn't yet have a wrapper for Path (and may never get it, because paths can have arbitrary structure) so we have to do an ugly ugly cast.

Arkadiy Kukarkin
  • 2,153
  • 14
  • 24