【问题标题】:Can't traverse to vertices with unique properties in Gremlin无法遍历 Gremlin 中具有独特属性的顶点
【发布时间】:2026-01-19 02:40:02
【问题描述】:

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

考虑这个例子:

    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() 这样的语句,但不是替换之前的赋值,而是将它们保存在数组或其他东西中?我怎样才能做到这一点?

谢谢

【问题讨论】:

    标签: graph gremlin tinkerpop


    【解决方案1】:

    您需要将当前的age 与之前看到的ages 进行比较。如果有任何匹配,让遍历器死亡:

    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()
    

    【讨论】: