My Graph looks like above image. It is simplified form of optical communication network. each vertex transmits one color. when two colors joins ("Mux") then it creates new color and transmits new light. At remote end colours are demuxed and passed to corresponding vertices. Mux,demux and transmit("straight") are captured as edge. New colors are formed as per vent diagram.
If I start from one color (ex. "Red"), then I have to traverse only through edge which have red (R1,R2) or red shade (D1,D2,P1).
For Example, If I start from R1, then I can traverse [R1,D1,D2,P1,R2]. it has another path [R1,D1,D2,P1,K1,R2] But it is not valid. As K1 doesn't have red shade.
Below query works well. I store the color while traversing through "mux" edge. And use this color to pick demux edge.
g.V().hasLabel("R1").
repeat(choose(values("type")).
option("mux", aggregate(local, "colors").by("color").inV()).
option("demux", filter(values("color").as("c").
where("c", new P(new BitiseAndPredicate(), "colors")).
by().
by(unfold().limit(1))
).inV()).
option("stright", __.inV()).simplePath()).
until(hasLabel("R2")).
path().by(label()).toList();
For Input "R1" to "R2" it works fine. [R1,tx,D1,tx,D2,tx,P1,tx,R2]
For "Y1" to "Y2" it returns empty. It is correct , As there is no edge from G1 to Y1.
I want to make changes to query. If it is not able to reach destination then print till where it reached .In this case [Y1,tx,D1,tx,D2,tx,G1]
I used emit(). But it prints all path combination along the path.
g.V().hasLabel("R1").
repeat(choose(values("type")).
option("mux", aggregate(local, "colors").by("color").inV()).
option("demux", filter(values("color").as("c").
where("c", new P(new BitiseAndPredicate(), "colors")).
by().
by(unfold().limit(1))
).inV()).
option("stright", __.inV()).simplePath()).
until(hasLabel("R2")).emit().
path().by(label()).toList();
If it is simple traversal then I can use emit(out().count().is(eq('0')))
. But in this case last edge have more edges, but not it is matching with my "mux & demux" condition. I can't reuse the same condition in "repeat" step. Actual implementation will be more complex.
Is there any way to emit path if until condition met or repeat step doesn't return any vertex.
Here is Java code
import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.util.function.Lambda;
import org.janusgraph.core.*;
import org.janusgraph.core.schema.JanusGraphManagement;
import java.util.ArrayList;
import java.util.List;
import static org.apache.tinkerpop.gremlin.process.traversal.P.eq;
import static org.apache.tinkerpop.gremlin.process.traversal.P.without;
import static org.apache.tinkerpop.gremlin.process.traversal.Scope.local;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.*;
import static org.janusgraph.core.Multiplicity.MULTI;
public class ColourTraversal
{
public static void main( String[] args )
{
//External db
GraphTraversalSource g =null;
//inmemory db
JanusGraph graph = JanusGraphFactory.build().set("storage.backend", "inmemory").open();
g = graph.traversal();
try
{
populateData(g);
g.tx().commit();
printPath(g, "R1", "R2");
System.out.println();
printPath(g, "Y1", "Y2");
g.close();
} catch (Exception e)
{
e.printStackTrace();
}
}
private static void printPath(GraphTraversalSource g, String start, String end)
{
List<Path> pathList = g.V().hasLabel(start).
repeat(repeatStep().simplePath()).
emit(hasLabel(end)).
path().by(label()).toList();
for (Path path : pathList)
{
for (int i = 0; i < path.size(); i++)
{
String label = path.get(i);
System.out.println(label);
}
}
}
private static GraphTraversal<?, Vertex> repeatStep()
{
GraphTraversal<?, ?> repeatStepTrav =
outE("tx").choose(values("type")).
option("mux", aggregate(local, "colors").by("color").inV()).
option("demux", filter(values("color").as("c").
where("c", new P(new BitiseAndPredicate(), "colors")).
by().
by(unfold().limit(1))
).inV()).
option("stright", __.inV());
return (GraphTraversal<Vertex, Vertex>) repeatStepTrav;
}
private static void populateData(GraphTraversalSource g)
{
Vertex r1 = g.addV("R1").next();
Vertex r2 = g.addV("R2").next();
Vertex d1 = g.addV("D1").next();
Vertex d2 = g.addV("D2").next();
Vertex g1 = g.addV("G1").next();
Vertex b1 = g.addV("B1").next();
Vertex b2 = g.addV("B2").next();
Vertex b3 = g.addV("B3").next();
Vertex y1 = g.addV("Y1").next();
Vertex p1 = g.addV("P1").next();
addEdge(g, r1, d1, "mux", 4);
addEdge(g, y1, d1, "mux", 2);
addEdge(g, b1, d1, "mux", 1);
addEdge(g, d1, d2, "stright", 7);
addEdge(g, g1, d2, "mux", 3);
addEdge(g, p1, d2, "mux", 5);
addEdge(g, b2, g1, "mux", 1);
addEdge(g, b3,p1, "mux", 1);
addEdge(g, r2,p1, "mux", 4);
addEdge(g, d1, r1, "demux", 4);
addEdge(g, d1, y1, "demux", 2);
addEdge(g, d1, b1, "demux", 1);
addEdge(g, d2, d1, "stright", 7);
addEdge(g, d2,g1, "demux", 3);
addEdge(g, d2,p1, "demux", 5);
addEdge(g, g1,b2, "demux", 1);
addEdge(g, p1,b3, "demux", 1);
addEdge(g, p1,r2, "demux", 4);
Vertex k1 = g.addV("K1").next();
addEdge(g, p1, k1, "demux", 0);
addEdge(g, k1, r2, "demux", 0);
addEdge(g, k1, p1, "mux", 0);
addEdge(g, r2, k1, "mux", 0);
// Vertex y2 = g.addV("Y2").next();
// addEdge(g, y2, g1, "mux", 2);
// addEdge(g, g1,y2, "demux", 2);
}
private static void addEdge(GraphTraversalSource g, Vertex source, Vertex destination,String type,int color) {
GraphTraversal t = g.V(source).addE("tx").to(destination).property("type", type).property("color", color);
t.next();
}
}
import java.util.function.BiPredicate;
public class BitisetAndPredicate implements BiPredicate {
@Override
public boolean test(Object o, Object o2) {
int left = (int) o;
int right = (int) o2;
return (left & right) == right;
}
}