Here is my graph:
Here is graph building code:
// backslashes included so the code can be copy and pasted into gremlin console
g\
.addV("Person").property(T.id, "A").as("a")\
.addV("Person").property(T.id, "B").as("b")\
.addV("Person").property(T.id, "C").as("c")\
.addV("Person").property(T.id, "D").as("d")\
.addV("Person").property(T.id, "E").as("e")\
.addV("Right").property(T.id, "1").property(set, "types", 1).property(set, "types", 2).as("r1")\
.addV("Right").property(T.id, "2").property(set, "types", 2).property(set, "types", 3).as("r2")\
.addV("Right").property(T.id, "3").property(set, "types", 4).property(set, "types", 5).as("r3")\
.addV("Right").property(T.id, "4").property(set, "types", 2).as("r4")\
.addE("receives").from("r1").to("a").property(T.id, "a")\
.addE("receives").from("b").to("r1").property(T.id, "b")\
.addE("receives").from("r2").to("b").property(T.id, "c")\
.addE("receives").from("r3").to("b").property(T.id, "d")\
.addE("receives").from("d").to("r3").property(T.id, "e")\
.addE("receives").from("c").to("r2").property(T.id, "f")\
.addE("receives").from("r4").to("c").property(T.id, "g")\
.addE("receives").from("e").to("r4").property(T.id, "h")
My requirement is to traverse the graph from A to E, checking the types property of Right vertices for intersections along the way - if the types intersect with the types from last step then select the edge for traversal, otherwise stop, ignoring the Right where the types do not intersect.
Here is what I tried so far:
g.withSack([2]).V("A").
repeat(
inE("receives").outV().
filter(values("types").fold().intersect(sack()).unfold().aggregate("inter")).
inE("receives").outV().as("current").
choose(inE().hasLabel("receives").count().is(0), select("current"), inE("receives").
outV().filter(values("types").fold().intersect(select("inter")).unfold()).inE("receives").outV()).
sack(assign).by(select("inter"))).
until(inE().hasLabel("receives").count().is(0))
There are problems with this query:
The initial value of the sack is hardcoded - when I tried to initialize it to the right of A (Right 1) the intersect() function does not work anymore
g.withSack([]).V("A").as("start").inE("receives").outV() .sack(assign).by(values("types").fold()) .select("start").repeat(
the values("types").fold() folds types for all nodes (on the frontier - is that how we say it?) and I want to evaluate the types per local step, do I need to factor 'local' in somehow
Can I achieve such dynamic, step-scoped filtering using intersections with Gremlin in Neptune?
withSack() works by collecting traversal results at the end of the repeat and is therefore not suitable for preserving dynamically calculated, per-traversal values between the repeats.
The only way I could get this to work as intended was by the way of using 'union' repeating inner traversals manually - so I had to have an idea of how deep the traversal may have to go.
This is far from ideal and if there is a better way I would invite the domain experts to comment on this answer.