Запрос Гремлина, чтобы найти весь подграф, с которым каким-либо образом связан конкретный узел.

Aug 19 2020

Я новичок в Гремлине и использую его gremlin-pythonдля обхода моего графика. Граф состоит из множества кластеров или подграфов, которые связаны между собой и не связаны ни с каким другим кластером в графе.

Простым примером этого является граф с 5 узлами и 3 ребрами:

  • Customer_1связан CreditCard_Aс 1_HasCreditCard_Aкраем
  • Customer_2связан CreditCard_Bс 2_HasCreditCard_Bкраем
  • Customer_3связан CreditCard_Aс 3_HasCreditCard_Aкраем

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

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

Например:

  • Если я указан Customer_1в запросе, в результате суб-граф будет содержать Customer_1, Customer_3, CreditCardA, 1_HasCreditCard_A, и 3_HasCreditCard_A.
  • Если я specififed Customer_2, возвращаемый суб-граф будет состоять из Customer_2, CreditCard_B, 2_HasCreditCard_B.
  • Если бы я запросил Customer_3, Customer_1будет возвращен тот же объект подграфа, который был возвращен из запроса.

Я использовал Neo4J с Cypher и Dgraph с GraphQL и нашел эту задачу довольно простой в этих двух языках, но я немного больше борюсь с пониманием гремлина.

РЕДАКТИРОВАТЬ:

Исходя из этого вопроса , выбранный ответ должен достичь того, чего я хочу, но без указания типа кромки, изменив его .both('created')на просто .both().

Однако синтаксис цикла: .loop{true}{true}конечно, недопустим в Python. Доступна ли эта функция цикла в gremlin-python? Я ничего не могу найти.

РЕДАКТИРОВАТЬ 2:

Я пробовал это, и, думаю, он работает, как ожидалось.

g.V(node_id).repeat(bothE().otherV().simplePath()).emit()

Это подходящее решение для того, что я ищу? Можно ли также включить в этот результат запрошенный узел?

Ответы

2 noam621 Aug 20 2020 at 13:51

Что касается второго редактирования, это выглядит как допустимое решение, которое возвращает все вершины, связанные с начальной вершиной. Небольшие исправления:

  • Вы можете изменить bothE().otherV()кboth()
  • если вы хотите получить также начальную вершину, вам нужно переместить emitшаг передrepeat
  • Я бы добавил dedupшаг, чтобы удалить все повторяющиеся вершины (может быть более 1 пути к вершине)
g.V(node_id).emit().repeat(both().simplePath()).dedup()

пример: https://gremlify.com/jngpuy3dwg9