无法遍历Gremlin中具有独特属性的顶点

时间:2019-02-08 06:23:05

标签: graph gremlin tinkerpop

我正在寻找从一个顶点到另一个顶点的路径,避免使用具有已经在该路径上匹配的属性的顶点。

考虑以下示例:

    Graph graph = TinkerGraph.open();

    GraphTraversalSource t = graph.traversal();

    Vertex A = t.addV().property("age", 19).next();
    Vertex B = t.addV().property("age", 21).next();
    Vertex C = t.addV().property("age", 20).next();
    Vertex D = t.addV().property("age", 21).next();
    Vertex E = t.addV().property("age", 22).next();

    t.V(A).addE("knows").to(B).iterate();
    t.V(B).addE("knows").to(C).iterate();
    t.V(C).addE("knows").to(D).iterate();
    t.V(D).addE("knows").to(E).iterate();
    t.V(C).addE("knows").to(E).iterate();

    List<Path> paths = t.V(A)
            .repeat(
                    out()
            ).times(5).emit()
            .has("age", 22).path().toList();

    Assert.assertEquals(1, paths.size());

我正在寻找从A到E的方法。有两种方法:

A-> B-> C-> D-> E A-> B-> C-> E

我要寻找的只是第二个,因为在第一个路径中,B和D具有相同的年龄。

我尝试使用as和by进行过滤,但是无法将其缩放到整个路径。例如,通过执行以下操作,我可以检查顶点不匹配第一个顶点的属性:

    List<Path> paths = t.V(A).as("first")
            .repeat(
                    out()
                    .where(P.neq("first")).by("age")
            ).times(5).emit()
            .has("age", 22).path().toList();

    Assert.assertEquals(1, paths.size());

但是您可以想象,它不会过滤路径中间的碰撞。我觉得应该有一种更简单的方法来实现此目的,而我却不这么想。是否有类似as()的语句,但是不是替换先前的赋值,而是将它们保留在数组中?我该如何实现?

谢谢

1 个答案:

答案 0 :(得分:1)

您需要将当前的age与先前看到的all相比较的age。如果有任何匹配,让遍历者死亡:

t.V(A).as("a").
  repeat(filter(loops().is(lt(5))).out().
         not(values("age").as("current").         /* current age   */
               select(all, "a").unfold().         /* previous ages */
               values("age").
                 where(eq("current"))).as("a")).  /* not() negates the match */
    until(has("age", 22)).
  path()