В этой статье вы освоите метод отладки сложных запросов Gremlin.

искусственный интеллект

Аннотация: Gremlin является наиболее распространенным базовым языком запросов для запросов к графовым базам данных. Полнота Gremlin по Тьюрингу позволяет писать очень сложные запросы. Как написать сложный запрос для сложных задач? И как нам понять сложные запросы, которые у нас уже есть? В этой статье вы шаг за шагом проведете отладку сложного запроса.

Эта статья опубликована в сообществе Huawei Cloud Community "Методы отладки сложных запросов Gremlin", оригинальный автор: Uncle_Tom.

1. Введение в Гремлин

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

Gremlin — это язык для описания блужданий в графах свойств. Обход графа выполняется в два этапа.

1.1. Источник обхода

Начать выбор узла. Все обходы начинаются с выбора набора узлов в базе данных, которые служат отправными точками для обхода графа. Обход в Gremlin начинается с TraversalSource. GraphTraversalSource предоставляет два метода обхода.

  • GraphTraversalSource.V(Object...ids): обход, начиная с вершин графа (все вершины, если идентификатор не указан).
  • GraphTraversalSource.E(Object...ids): обход, начиная с ребер графа (все ребра, если идентификатор не указан).

1.2 Обход графа

Прогулка по графу. Начиная с узла, выбранного на предыдущем шаге, обход продолжается вдоль ребер графа, чтобы достичь соседних узлов в зависимости от свойств и типов узлов и ребер. Конечная цель обхода — определить все узлы, до которых можно добраться при обходе. Вы можете думать об обходе графа как об описании подграфа, которое должно быть выполнено, чтобы вернуть узел.

Тип возвращаемого значения V() и E() — GraphTraversal. GraphTraversal поддерживает ряд методов, которые возвращают GraphTraversal. GraphTraversal поддерживает функциональную композицию. Каждый метод GraphTraversal называется шагом, и каждый шаг модулирует результат предыдущего шага одним из пяти обычных способов.

  1. карта: преобразовать входящий объект обхода в другой объект (S→E).
  2. flatMap: преобразовать входящий объект обхода в итератор других объектов (S\subseteq E^*_S_⊆_E_∗).
  3. фильтр: Разрешить или запретить обходчику переходить к следующему шагу (S→S∪∅).
  4. sideEffect: позволяет обходчику оставаться неизменным, но в процессе возникают некоторые вычислительные побочные эффекты (S↬S).
  5. ветвь: разделить обходчик и отправить его в любую позицию обхода (S→{S1→E^*,…,S_n→E^*_S_1→_E_∗,…,_Sn_​→_E_∗}→E*) .

  • Почти каждый шаг в GraphTraversal наследуется от MapStep, FlatMapStep, FilterStep, SideEffectStep или BranchStep.

  • Пример: Найдите кого-нибудь, кто знает макросы

    gremlin> g.V().has('name','marko').out('knows').values('name') ==>vadas ==>josh

1.3. Гремлин — это полный Turning Complete

Это означает, что любая сложная проблема может быть описана Гремлином.

Ниже приведены рекомендации и методология отладки и написания сложных запросов гремлинов.

2. Отладка сложных запросов Gremlin

Запросы Gremlin состоят из простых запросов в сложные запросы. Поэтому сложные запросы Gremlin можно разделить на следующие три шага, а проверку всех операторов можно выполнять итеративно.Этот метод также подходит для написания сложных запросов Gremlin.

2.1. Итеративные этапы отладки

  1. Разделите шаги анализа, разделите большие на маленькие и проверяйте шаг за шагом;
  2. Вывод результатов шагов и уточнение конкретного выходного содержания шагов;
  3. Получите и проверьте выходные результаты. Расширьте или сузьте шаги анализа на основе результатов, вернитесь к шагу 1 и продолжайте, пока все результаты не станут ясными.
  • ПРИМЕЧАНИЕ. Этот метод относится к логике анализа и варианту использования анатомии гремлинов Стивена Маллетта.

2.2 Варианты использования

2.2.1 Структура графика

gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin>g.addV().property('name','alice').as('a').
  addV().property('name','bobby').as('b').
  addV().property('name','cindy').as('c').
  addV().property('name','david').as('d').
  addV().property('name','eliza').as('e').
  addE('rates').from('a').to('b').property('tag','ruby').property('value',9).
  addE('rates').from('b').to('c').property('tag','ruby').property('value',8).
  addE('rates').from('c').to('d').property('tag','ruby').property('value',7).
  addE('rates').from('d').to('e').property('tag','ruby').property('value',6).
  addE('rates').from('e').to('a').property('tag','java').property('value',10).
  iterate()
gremlin> graph
==>tinkergraph[vertices:5 edges:5]

2.2.2 Оператор запроса

gremlin>g.V().has('name','alice').as('v').
   repeat(outE().as('e').inV().as('v')).
     until(has('name','alice')).
   store('a').
     by('name').
   store('a').
     by(select(all, 'v').unfold().values('name').fold()).
   store('a').
     by(select(all, 'e').unfold().
        store('x').
          by(union(values('value'), select('x').count(local)).fold()).
        cap('x').
        store('a').by(unfold().limit(local, 1).fold()).unfold().
        sack(assign).by(constant(1d)).
        sack(div).by(union(constant(1d),tail(local, 1)).sum()).
        sack(mult).by(limit(local, 1)).
        sack().sum()).
   cap('a')
==>[alice,[alice,bobby,cindy,david,eliza,alice],[9,8,7,6,10],18.833333333333332]

Так долго и так сложно! большая голова!

Посмотрите, как я сдираю кокон и шаг за шагом проверяю результаты.

2.3 Процесс отладки

2.3.1 Разделить запрос

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

  • Выполните первую часть шагов

    gremlin> g.V().has('name','alice').as('v'). ......1> repeat(outE().as('e').inV().as('v')). ......2> until(has('name','alice')) ==>v[0]

2.3.2 Уточнение результатов

Здесь информация об узле выводится через valueMap().

gremlin> g.V().has('name','alice').as('v').
......1> repeat(outE().as('e').inV().as('v')).
......2> until(has('name','alice')).valueMap()
==>[name:[alice]]

2.3.3 Проверка гипотезы

Процесс запроса выводится в соответствии с семантикой выполняемого оператора следующим образом:

Используйте path(), чтобы проверить процесс вывода

g.V().has('name','alice').as('v').
......1> repeat(outE().as('e').inV().as('v')).
......2> until(has('name','alice')).path().next()
==>v[0]
==>e[10][0-rates->2]
==>v[2]
==>e[11][2-rates->4]
==>v[4]
==>e[12][4-rates->6]
==>v[6]
==>e[13][6-rates->8]
==>v[8]
==>e[14][8-rates->0]
==>v[0]
  • Выходной результат согласуется с результатом вывода, разверните оператор запроса и вернитесь к шагу 1;

  • Если результаты противоречивы или непонятны, сузьте объем шагов, вы можете использовать предыдущий шаг запроса на этом шаге и вернуться к шагу 1;

  • И так до тех пор, пока весь запрос не будет полностью понят.

    gremlin> g.V().has('name','alice').as('v'). ......1> repeat(outE().as('e').inV().as('v')). ......2> until(has('name','alice')). ......3> store('a').by('name') ==>v[0]

Бамбуковые побеги вы можете отклеить самостоятельно, здесь опущено 3000 слов.

3. Резюме

  • В процессе анализа для пошагового понимания используется метод деления высказывания-запроса, а для постепенного расширения понимания высказывания – метод воронки;
  • Для результата запроса каждого шага вы можете использовать такие функции, как valueMap(), path(), select(), as(), cap() для вывода и проверки результатов;
  • Для шагов с неясными результатами или несовместимыми с ожидаемыми значениями уменьшите шаг запроса и используйте предыдущий шаг шага вывода в качестве точки вывода для вывода и проверки;
  • Когда результат данных верхнего уровня ясен, можно использовать метод inject() для ввода выходных данных верхнего уровня, а последующий вывод и проверку можно продолжить;
  • Обратите внимание на влияние функции в конце шага на общий результат.

4. Ссылка

  • Introduction to Gremlin

  • Анатомия Гремлина

  • TinkerPop Documentation

  • Stephen Mallette gremlins-anatomy

  • Practical Gremlin - Why Graph?

Нажмите «Подписаться», чтобы впервые узнать о новых технологиях HUAWEI CLOUD~