Как я могу собирать значения свойств при обходе графика с помощью gremlin в Java?

# #java #gremlin

Вопрос:

Каждая вершина в моем графике имеет, по крайней мере, свойство name. У меня есть метка L, набор S значений имен. Теперь я хочу собрать значения свойства name для всех вершин, которые могут быть достигнуты (рекурсивно) с помощью определенного исходящего ребра с меткой ребра EL из вершин с именами в наборе S.

Мое текущее решение для одного начального узла с именем 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 делается только для того, чтобы убедиться, что это дает ожидаемый результат, обычно я собираю имена в набор.

Есть ли лучший способ собрать значения свойства name всех вершин, доступных через исходящие ребра с меткой EL?

И каков был бы лучший способ начать с нескольких вершин (где известно только имя из множества S)?

В настоящее время структура представляет собой дерево, но если возможны циклы, предотвращает ли приведенный выше код бесконечные циклы? Если нет, то как это можно сделать?

Ответ №1:

Ваш подход — хорошее начало.

Чтобы начать с набора из нескольких вершин, используйте P.within() предикат. TinkerPop предоставляет несколько других предикатов.

Используйте simplePath() для предотвращения повторения сквозных циклов.

Используется store() для отслеживания элементов по мере прохождения графика. by("name") Модулятор будет хранить свойство «имя», а не вершину.

Чтобы получить результат, используйте cap() для вывода элементы, которые он сохранил во время обхода. Результатом на этом этапе является a 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()