java - TinkerPop 图中的深度优先树遍历

标签 java graph-databases gremlin tinkerpop3

给定一个树形结构的 TinkerPop 图,其顶点通过标记的父子关系 ([parent-PARENT_CHILD->child]) 连接,遍历并查找所有这些节点的惯用方法是什么?

我是图形遍历的新手,因此使用递归函数遍历它们似乎或多或少简单:

Stream<Vertex> depthFirst(Vertex v) {
  Stream<Vertex> selfStream = Stream.of(v);
  Iterator<Vertex> childIterator = v.vertices(Direction.OUT, PARENT_CHILD);
  if (childIterator.hasNext()) {
    return selfStream.appendAll(
      Stream.ofAll(() -> childIterator)
        .flatMap(this::depthFirst)
    );
  }
  return selfStream;
}

(注意,此示例使用 Vavr 流,但 Java 流版本类似,只是稍微更详细。)

我认为图 native 实现的性能会更高,尤其是在内存 TinkerGraph 以外的数据库上。

但是,当我查看 TinkerPop tree recipes 时,目前尚不清楚 repeat()/until() 等的哪种组合最适合执行我想要的操作。

如果我只想查找具有特定标签的顶点(叶子或分支),我可以再次了解如何使用上面的函数来做到这一点:

Stream<Vertex> nodesWithMyLabel = depthFirst(root)
  .filter(v -> "myLabel".equals(v.label()));

但这是否有效还远非显而易见,我认为一定有更好的图原生方法。

最佳答案

如果您使用 TinkerPop,最好只使用 Gremlin 编写遍历。让我们使用配方中描述的树:

g.addV().property(id, 'A').as('a').
  addV().property(id, 'B').as('b').
  addV().property(id, 'C').as('c').
  addV().property(id, 'D').as('d').
  addV().property(id, 'E').as('e').
  addV().property(id, 'F').as('f').
  addV().property(id, 'G').as('g').
  addE('hasParent').from('a').to('b').
  addE('hasParent').from('b').to('c').
  addE('hasParent').from('d').to('c').
  addE('hasParent').from('c').to('e').
  addE('hasParent').from('e').to('f').
  addE('hasParent').from('g').to('f').iterate()

要查找“A”的所有子级,您只需执行以下操作:

gremlin> g.V('A').repeat(out()).emit()
==>v[B]
==>v[C]
==>v[E]
==>v[F]

上面的遍历基本上是说,“从‘A’顶点开始,遍历出边,直到没有更多的边,哦,顺便说一句,当你去的时候发出每个子顶点。”如果你也想这样做得到“A”的根,然后你只需要稍微改变一下:

gremlin> g.V('A').emit().repeat(out())
==>v[A]
==>v[B]
==>v[C]
==>v[E]
==>v[F]

更进一步,如果您只想根据某个过滤器(在您指定的标签中的问题中)发出某些顶点,您只需为 emit() 提供一个过滤参数即可。在这种情况下,我只发出那些具有多个传入边的顶点:

gremlin> g.V('A').emit(inE().count().is(gt(1))).repeat(out())
==>v[C]
==>v[F]

关于java - TinkerPop 图中的深度优先树遍历,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47841672/

相关文章:

Maven - 在构建项目时使用 -source 5 或更高版本来启用...

java - JFrame 屏幕闪烁白光和黑光

postgresql - 与其他图数据库相比,AgensGraph 重吗?

python - ArangoDB:尝试使用 gharial 接口(interface)创建顶点时出现服务器错误

Gremlin:如何克服属性空问题并编写更新某个顶点的所有属性的查询?

java - '? 附近更新查询中的语法错误在 Eclipse 中但在 MySQL Workbench 中工作

scala - 是否可以为顶点中的标签建立索引

gremlin - 如何在 Gremlin 中使用 UUID 作为 id?

amazon-web-services - 如何为通过 CSV 导入 AWS Neptune 的 Vertex 属性安排单一基数?

Java 外观 - 如何打破对 sun.swing.SwingUtilities2 的依赖