Search code examples
gremlintinkerpop3

How to access stored variable from repeat step in tinkerpop


Group of vertices and edges

I am just Two days in to gremlin. I have set of vertices and colored edges. I want to find path from S2 to D2. If I enter to black vertex through green edge ( G1 -B1) then I have to come out only through green edge (B2-G2) . I should n't come out of red edge.

Below query works, But I can’t hardcode colors (has('color',within("green") in 3rd line).

 g.V().hasLabel("S2").repeat(outE("tx").choose(values("type")).
      option("multiplex",aggregate(local,"colors").by("color").inV()).
      option("demultiplex",has('color',within("green")).inV()).
      option(none,__.inV()).
      simplePath()).until(hasLabel("D2")).path().by(label())

So I tried below query It doesn’t give any path. If my edge has label “multiplex” then I store the color . If my edge has label “demultiplex” then I read the color from store.

 g.V().hasLabel("S2").repeat(outE("tx").choose(values("type")).
      option("multiplex",aggregate("colors").by("color").inV()).
      option("demultiplex",has("color",within(select("colors").unfold())).inV()).
      option(none,__.inV()).
      simplePath()).until(hasLabel("D2")).path().by(label())

Below code populates the graph

 Vertex s1 = g.addV("S1").next();
    Vertex s2 = g.addV("S2").next();
    Vertex d1 = g.addV("D1").next();
    Vertex d2 = g.addV("D2").next();
    Vertex r1 = g.addV("R1").next();
    Vertex r2 = g.addV("R2").next();
    Vertex r3 = g.addV("R3").next();
    Vertex r4 = g.addV("R4").next();
    Vertex g1 = g.addV("G1").next();
    Vertex g2 = g.addV("G2").next();
    Vertex g3 = g.addV("G3").next();
    Vertex g4 = g.addV("G4").next();
    Vertex b1 = g.addV("B1").next();
    Vertex b2 = g.addV("B2").next();
    Vertex b3 = g.addV("B3").next();
    Vertex b4 = g.addV("B4").next();


    g.V(s1).addE("tx").to(r1).property("type","straight").next();
    g.V(r1).addE("tx").to(b1).property("color","red").property("type","multiplex").next();

    g.V(s2).addE("tx").to(g1).property("type","straight").next();
    g.V(g1).addE("tx").to(b1).property("color","green").property("type","multiplex").next();

    g.V(b1).addE("tx").to(b2).property("type","straight").next();


    g.V(b2).addE("tx").to(r2).property("color","red").property("type","demultiplex").next();

    g.V(b2).addE("tx").to(g2).property("color","green").property("type","demultiplex").next();

    g.V(r2).addE("tx").to(r3).property("type","straight").next();
    g.V(g2).addE("tx").to(g3).property("type","straight").next();

    g.V(r3).addE("tx").to(b3).property("color","red").property("type","multiplex").next();

    g.V(g3).addE("tx").to(b3).property("color","green").property("type","multiplex").next();


    g.V(b3).addE("tx").to(b4).property("type","straight").next();


    g.V(b4).addE("tx").to(g4).property("color","green").property("type","demultiplex").next();

    g.V(g4).addE("tx").to(d2).property("type","straight").next();

    g.V(b4).addE("tx").to(r4).property("color","red").property("type","demultiplex").next();
    g.V(r4).addE("tx").to(d1).property("type","straight").next();

Solution

  • You were pretty close. This syntax is always tempting:

    has("color",within(select("colors").unfold())
    

    but it doesn't work that way as you've found. That P syntax doesn't take a Traversal that way. You need to use a form of where() when you need to reference a side-effect (i.e. "colors").

    gremlin> g.V().hasLabel("S2").
    ......1>   repeat(outE("tx").
    ......2>          choose(values("type")).
    ......3>            option("multiplex",aggregate(local,"colors").by("color").inV()).
    ......4>            option("demultiplex", filter(values('color').as('c').
    ......5>                                         where('c',eq('colors')).
    ......6>                                           by().
    ......7>                                           by(unfold().tail())).inV()).
    ......8>            option(none,__.inV()).
    ......9>          simplePath()).
    .....10>     until(hasLabel("D2")).
    .....11>   path().by(label)
    ==>[S2,tx,G1,tx,B1,tx,B2,tx,G2,tx,G3,tx,B3,tx,B4,tx,G4,tx,D2]