Gremlin ищет вершины, связанные с 2 или более конкретными узлами

Я пытаюсь создать запрос Gremlin, в котором мне нужно найти вершины, у которых есть ребра из определенных других вершин. Менее абстрактной версией этого запроса является то, что у меня есть пользовательские вершины, и они связаны с групповыми вершинами (то есть предметами в школе, то есть учащимися, которые изучают "математика 6-го года" и "английский язык 6-го года" и т. Д.). Дополнительной трудностью является возможность существования подгрупп в этом запросе.

В запросе мне нужно найти тех пользователей, которые входят в 2 или более групп, указанных пользователем.

В настоящее время у меня есть краткое решение, но в производственном использовании с использованием Amazon Netpune этот запрос выполняется слишком плохо, даже с небольшим объемом данных. Я уверен, что есть более простой способ достичь этого:/

g.V()
.has('id', 'group_1')
.repeat(out("STUDENT", "SUBGROUP"))
.until(hasLabel("USER"))
.aggregate("q-1")
.V()
.has('id', 'group_2')
.repeat(out("STUDENT", "SUBGROUP"))
.until(hasLabel("USER"))
.where(within("q-1"))
.aggregate("q-2")
.V()
.hasLabel(USER)
.where(within("q-2"))
# We add some more filtering here, such as search terms
.dedup()
.range(0, 10)
.values("id")
.toList()

1 ответ

Первое серьезное изменение, которое вы можете сделать, это не беспокоить итерацию всех V() снова для "USER" - это уже тот вывод, который был получен на предыдущих этапах, поэтому сбор "q-2" только для того, чтобы использовать его для фильтра, не кажется необходимым:

g.V().
  has('id', 'group_1').
  repeat(out("STUDENT", "SUBGROUP")).
    until(hasLabel("USER")).
  aggregate("q-1").
  V().
  has('id', 'group_2').
  repeat(out("STUDENT", "SUBGROUP")).
    until(hasLabel("USER")).
  where(within("q-1")).
  # We add some more filtering here, such as search terms
  dedup().
  range(0, 10).
  values("id")

Это уже должно быть огромной экономией для вашего запроса, потому что это изменение позволяет избежать итерации всего графа в памяти (то есть полного сканирования всех вершин), так как там не было поиска индекса.

Я не знаю, какие у вас дополнительные фильтры здесь:

# We add some more filtering here, such as search terms 

но я бы определенно попытался отфильтровать пользователей раньше в вашем запросе, а не позже. Возможно, рассмотрите возможность использования emit() на ваше repeats() фильтровать лучше. Вы, вероятно, также должны dedup() ваш "q-1" и уменьшите размер списка там.

Мне было бы любопытно узнать, насколько сработает только начальное изменение, которое я предложил, поскольку это, вероятно, самая большая часть стоимости вашего запроса (если, конечно, у вас нет действительно глубокого / широкого дерева учащихся / подгрупп). Возможно, здесь есть еще кое-что, но было бы неплохо знать, что у вас, по крайней мере, есть обходной путь с удовлетворительной производительностью на этом этапе.

Другие вопросы по тегам