如何在Java中使用gremlin遍历图形时收集属性值?

2022-05-12 00:00:00 gremlin java

我的图中的每个顶点至少有一个名称属性。我有一个名称值的标签L集合S。现在,我想从集合S中具有名称的顶点中收集可通过带有边标签EL的特定传出边(递归地)到达的所有顶点的名称属性值。

我当前针对名为s1的单个开始节点的解决方案如下所示:

            g.traversal().V().hasLabel(L)
            .has("name", S1)
            .repeat(__.optional(__.out(EL)))
            .until(__.out(EL).count().is(0))
            .path()
            .forEachRemaining(path -> {
             path.forEach(e -> System.out.println(((Vertex)e).property("name").value()));});

println只是为了看到这会产生预期的结果,通常我会将姓名收集在一组中。

是否有更好的方法来收集可通过标签为EL的传出边到达的所有顶点的名称属性值?

从多个顶点(其中只知道集合S中的名称)开始的最佳方法是什么?

目前,该结构是一个树,但如果可能存在循环,上面的代码是否可以防止无尽的循环?如果没有,如何做到这一点?


解决方案

您的方法是一个良好的开端。

要从一组多个顶点开始,请使用P.within()谓词。TinkerPop提供了几个other predicates。

使用simplePath()防止循环重复。

使用store()跟踪遍历图形的项目。by("name")调制器将存储"name"属性,而不是顶点。

要得到结果,请使用cap()输出它在遍历过程中存储的项。此时的结果是可能包含重复项的Set。使用unfold()Set转换为我们可以dedup()然后使用toSet()完成的迭代器。

graph.traversal().V().hasLabel(L).has("name", P.within(S)).
  repeat( __.out(EL).simplePath().store("x").by("name") ).
  until( __.outE(EL).count().is(0) ).
  cap("x").unfold().dedup().toSet()

相关文章