如何在Java中使用gremlin遍历图形时收集属性值?
我的图中的每个顶点至少有一个名称属性。我有一个名称值的标签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()
相关文章