This looks like a bug in 3.2.3. It's clearly expected to fail, since by()
modulators should always fail if the traverser can't emit a value. What you
actually want to do is this:
gremlin> g.traversal().V(a1.id()).optional(
......1> outE("ab").as("e").otherV().as("vb").optional(
......2> outE("bc").as("e").otherV().as("vc"))).
......3> order().by(select(first, "e").by("order")).
......4> by(select(last, "e").by("order")).values("name")
==>b3
==>b2
==>c3
==>c2
==>c1
Not related to your problem, but I thought I should point that out: don't
use otherV() when you know the direction.
g.traversal().V(a1.id()).optional(
outE("ab").as("e").inV().as("vb").optional(
outE("bc").as("e").inV().as("vc"))).
order().by(select(first, "e").by("order")).
by(select(last, "e").by("order")).values("name")
Also, some labels are redundant in this particular traversal; get rid of
them:
g.traversal().V(a1.id()).optional(
outE("ab").as("e").inV().optional(
outE("bc").as("e").inV())).
order().by(select(first, "e").by("order")).
by(select(last, "e").by("order")).values("name")
Oh, and there's something else: The query would fail if there wouldn't be a
single "ab" edge. If you want to take this into account, do:
g.traversal().V(a1.id()).optional(
outE("ab").as("e").inV().optional(
outE("bc").as("e").inV())).
order().by(coalesce(select(first, "e").by("order"), constant(0))).
by(coalesce(select(last, "e").by("order"),
constant(0))).values("name")
And finally, pointing out the obvious: don't create a new traversal source
for every query.
That's it.
Cheers,
Daniel
On Sat, Feb 11, 2017 at 3:03 PM, pieter-gmail <[email protected]>
wrote:
> Hi,
>
> The following query no longer works on 3.2.4
>
> @Test
> public void testOptionalWithOrderBy() {
> final TinkerGraph g = TinkerGraph.open();
> Vertex a1 = g.addVertex(T.label, "A", "name", "a1");
> Vertex b1 = g.addVertex(T.label, "B", "name", "b1");
> Vertex b2 = g.addVertex(T.label, "B", "name", "b2");
> Vertex b3 = g.addVertex(T.label, "B", "name", "b3");
> Vertex c1 = g.addVertex(T.label, "C", "name", "c1");
> Vertex c2 = g.addVertex(T.label, "C", "name", "c2");
> Vertex c3 = g.addVertex(T.label, "C", "name", "c3");
> a1.addEdge("ab", b1, "order", 3);
> a1.addEdge("ab", b2, "order", 2);
> a1.addEdge("ab", b3, "order", 1);
> b1.addEdge("bc", c1, "order", 3);
> b1.addEdge("bc", c2, "order", 2);
> b1.addEdge("bc", c3, "order", 1);
> GraphTraversal<Vertex, Vertex> traversal = g.traversal().V(a1.id
> ())
> .optional(
> __.outE("ab").as("ab").otherV().as("vb")
> .optional(
>
> __.outE("bc").as("bc").otherV().as("vc")
> )
> )
> .order().by(__.select("ab").by("order"),
> Order.incr).by(__.select("bc").by("order"), Order.incr);
> while (traversal.hasNext()) {
> System.out.println(traversal.next().<String>value("name"));
> }
> }
>
> On 3.2.3 it returns
>
> b3
> b2
> c3
> c2
> c1
>
> On 3.2.4 it throws the following exception,
>
> java.lang.IllegalArgumentException: The provided traverser does not map
> to a value: v[6]->[SelectOneStep(bc,value(order))]
> at
> org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil.apply(
> TraversalUtil.java:45)
> at
> org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderGlobalStep.
> createProjectedTraverser(OrderGlobalStep.java:155)
> at
> org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderGlobalStep.
> processAllStarts(OrderGlobalStep.java:74)
> at
> org.apache.tinkerpop.gremlin.process.traversal.step.util.
> CollectingBarrierStep.processNextStart(CollectingBarrierStep.java:108)
> at
> org.apache.tinkerpop.gremlin.process.traversal.step.util.
> AbstractStep.hasNext(AbstractStep.java:143)
> at
> org.apache.tinkerpop.gremlin.process.traversal.util.
> DefaultTraversal.hasNext(DefaultTraversal.java:184)
>
> Has the semantics changed or is it a bug?
>
> Thanks
> Pieter
>
>