Учитывая древовидный граф 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 аналогична, только немного более подробна .)
Я предполагаю, что реализация на основе графа будет более производительной, особенно в базах данных, отличных от TinkerGraph в памяти.
Однако, когда я смотрю на древовидные рецепты TinkerPop, не совсем понятно, какие комбинация repeat()
/ until()
и т. д. является правильной, чтобы делать то, что я хочу.
Если я затем хочу найти только те вершины (лист или ветвь) с определенной меткой, я снова могу увидеть, как это сделать с помощью функции выше:
Stream<Vertex> nodesWithMyLabel = depthFirst(root)
.filter(v -> "myLabel".equals(v.label()));
но далеко не очевидно, что это эффективно, и я предполагаю, что должен быть лучший подход, основанный на графах.