Gremlin — это язык обхода графов и виртуальная машина , разработанный Apache TinkerPop из Apache Software Foundation . Gremlin работает как с графовыми базами данных на основе OLTP , так и с графовыми процессорами на основе OLAP . Автоматы и функциональный язык Gremlin позволяют Gremlin естественно поддерживать: императивные и декларативные запросы; агностицизм принимающего языка; определяемые пользователем языки домена ; расширяемый компилятор/оптимизатор, модели выполнения на одной и нескольких машинах; гибридная оценка в глубину и в ширину с полнотой по Тьюрингу . [2]
В качестве поясняющей аналогии: Apache TinkerPop и Gremlin предназначены для графического отображения баз данных, то же самое, что JDBC и SQL для реляционных баз данных . Аналогично, машина обхода Gremlin предназначена для графического отображения вычислений так же, как виртуальная машина Java для вычислений общего назначения. [3]
Gremlin — это язык обхода графов под лицензией Apache2 , который могут использовать поставщики графовых систем. Обычно существует два типа поставщиков графовых систем: графовые базы данных OLTP и графовые процессоры OLAP. В таблице ниже указаны поставщики графов, поддерживающие Gremlin.
Следующие примеры запросов и ответов Gremlin в среде Gremlin-Groovy относятся к графическому представлению набора данных MovieLens. [4] В набор данных входят пользователи, которые оценивают фильмы. У каждого пользователя есть одно занятие, и с каждым фильмом связана одна или несколько категорий. Схема графа MovieLens подробно описана ниже.
пользователь -- рейтинг [ звезды : 0–5 ] --> пользователь фильма -- род деятельности --> фильм профессия -- категория -- > категория
Для каждой вершины графа выдайте ее метку, затем сгруппируйте и подсчитайте каждую отдельную метку.
гремлин > г . В (). этикетка (). groupCount () ==>[ профессия: 21 , фильм: 3883 , категория: 18 , пользователь: 6040 ]
В каком году был снят самый старый фильм?
гремлин > г . В (). hasLabel ( «фильм» ). значения ( «год» ). мин () ==> 1919
Какой средний рейтинг у «Крепкого орешка»?
гремлин > г . В (). имеет ( «фильм» , «имя» , «Крепкий орешек» ). inE ( «рейтинг» ). ценности ( «звезды» ). среднее () ==> 4.121848739495798
Для каждой категории создайте карту с ее названием и количеством фильмов, которые она представляет.
гремлин > г . В (). hasLabel ( «категория» ). как ( 'а' , 'б' ). выберите ( 'a' , 'b' ). по имени ' ). by ( inE ( 'category' ). count ()) ==>[ a : Анимация , b: 105 ] ==>[ a: Детская , b : 251 ] ==>[ a: Комедия , b: 1200 ] ==>[ a: Приключения , b: 283 ] ==>[ a: Фэнтези , b: 68 ] ==>[ a: Романтика , b: 471 ] ==>[ a: Драма , b: 1603 ] = =>[ a: Экшен , b: 503 ] ==>[ a: Криминал , b: 211 ] ==>[ a: Триллер , b: 492 ] ==>[ a: Ужасы , b: 343 ] ==> [ a: Научная фантастика , b: 276 ] ==>[ a: Документальный , b: 127 ] ==>[ a: Война , b: 143 ] ==>[ a: Мюзикл , b : 114 ] ==> [ a: Тайна , b: 106 ] ==>[ a: Фильм - Нуар , b: 44 ] ==>[ a: Вестерн , b: 68 ]
Для каждого фильма, имеющего не менее 11 оценок, выведите карту его названия и среднего рейтинга. Отсортируйте карты в порядке убывания их среднего рейтинга. Выпустите первые 10 карт (т.е. 10 лучших).
гремлин > г . В (). hasLabel ( «фильм» ). как ( 'а' , 'б' ). где ( inE ( 'rated' ). count (). is ( gt ( 10 ))). выберите ( 'a' , 'b' ). по имени ' ). по ( inE ( 'rated' ). values ( 'stars' ). mean ()). заказ (). by ( select ( 'b' ), decr ). предел ( 10 ) ==>[ a : Сандзюро , b: 4.608695652173913 ] ==>[ a: Семь самураев ( Великолепная семерка ), b: 4.560509554140127 ] ==>[ a: Побег из Шоушенка , The , b: 4.554557700942973 ] = =>[ a: Крестный отец , The , b: 4.524966261808367 ] ==>[ a: Гладкое бритье , A , b: 4.52054794520548 ] ==>[ a: Обычные подозреваемые , The , b: 4.517106001121705 ] ==>[ a: Шиндлер ' s List , b: 4.510416666666667 ] ==>[ a : Неправильные брюки , The , b: 4.507936507936508 ] ==>[ a: Sunset Blvd. ( a . k . a . Бульвар Сансет ), b: 4.491489361702127 ] ==>[ a: В поисках утраченного ковчега , b : 4.47772 ]
Gremlin поддерживает декларативное сопоставление шаблонов графов, аналогично SPARQL . Например, следующий запрос ниже использует шаг Gremlin match() .
Какие боевики 80-х нравятся тридцатилетним программистам? Сгруппируйте фильмы по их названию и отсортируйте карту подсчета групп в порядке убывания по значению. Закрепите карту до 10 лучших и опубликуйте записи карты.
гремлин > г . В (). match ( __ . as ( 'a' ). hasLabel ( 'movie' ), __ . as ( 'a' ). out ( 'category' ). has ( 'name' , 'Action' ), __ . as ( ' a' ), имеет ( ' year' , между ( 1980 , 1990 ) ), __ как ( ' a' ), inE ( 'rated' ), __ как ( ' b ' ) . имеет ( 'звезды' , 5 ) , __ . как ( ' b' ). outV (). как ( ' c' ) , __ . out ( ' оккупация ' ) . , 'программист' ), __ . как ( 'c' ), ( ' возраст' , между ( 30 , 40 ))). выберите ' ) . ГруппаКаунт (). по имени ' ). заказ ( местный ). по ( valueDecr ). лимит ( локальный , 10 ) ==> В поисках утраченного ковчега = 26 ==> Эпизод V Звездных войн - Империя наносит ответный удар = 26 == > Терминатор ,The = 23 ==> Звездные войны . Эпизод VI — Возвращение джедая = 22 ==> Принцесса - невеста , The = 19 == > Пришельцы = 18 ==> Лодка ( Das Boot ) = 11 ==> Индиана Джонс и Последний крестовый поход = 11 == > Звездный путь : Гнев Хана = 10 == > Бездна , = 9
Какие фильмы занимают центральное место в неявном графике 5 звезд?
гремлин > g = график . обход ( компьютер ( SparkGraphComputer )) ==> Graphtraversalsource [ hadoopgraph [ gryoinputformat -> gryooutputformat ], sparkgraphcomputer ] gremlin > g . В (). повтор ( outE ( «рейтинг» ). has ( 'звезды' , 5 ). inV (). groupCount ( 'm' ). by ( 'имя' ). inE ( 'рейтинг' ). has ( 'звезды' , 5 ). ) . раз ( 4 ). кепка ( 'm' ) ==> « Звездные войны . Эпизод IV . Новая надежда» 35405394353105332 == > Красота по-американски 31943228282020585 ==> В поисках утраченного ковчега 312224779793238499 ==> « Звездные войны . Эпизод V. Империя наносит ответный удар » 30434677119726223 ==> Крестный отец , 30258518523013057 == > Побег из Шоушенка , 28297717387901031 == > Список Шиндлера 27539336654199309 == > Молчание ягнят , 26736276376806173 == > Фарго 26531 050311325270 == > Матрица , 26395118239203191
Gremlin — это виртуальная машина , состоящая из набора команд и механизма выполнения. Проводится аналогия между Gremlin и Java .
Следующий обход — это обход Gremlin на диалекте Gremlin-Java8.
г . В (). как " ) . вне ( «знает» ). как ( «б» ). выберите ( «а» , «б» ). по имени" ) . по ( «возрасту» )
Язык Gremlin (т.е. свободный стиль описания обхода графа) может быть представлен на любом основном языке, который поддерживает композицию функций и вложение функций . Из-за этого простого требования существуют различные диалекты Gremlin, включая Gremlin-Groovy, Gremlin-Scala, Gremlin-Clojure и т. д. Приведенный выше обход Gremlin-Java8 в конечном итоге компилируется в последовательность шагов, называемую обходом . Строковое представление описанного выше обхода представлено ниже.
[ GraphStep ( [] , вершина ) @ [ a ] , VertexStep ( OUT , [ знает ] , вершина ) @ [ b ] , SelectStep ( [ a , b ] , [ значение ( имя ), значение ( возраст ) ] ) ]
Шаги представляют собой примитивы машины обхода графа Гремлина. Это параметризованные инструкции, которые в конечном итоге выполняет машина. Набор инструкций Gremlin составляет примерно 30 шагов. Этих шагов достаточно для обеспечения вычислений общего назначения и того, что обычно требуется для выражения общих мотивов любого запроса обхода графа.
Учитывая, что Gremlin — это язык, набор команд и виртуальная машина, можно разработать другой язык обхода, который компилируется в машину обхода Gremlin (аналогично тому, как Scala компилируется в JVM ). Например, популярный язык сопоставления шаблонов графов SPARQL можно скомпилировать для выполнения на машине Gremlin. Следующий запрос SPARQL
ВЫБЕРИТЕ ?a ?b ?c WHERE { ?a a Person . ?a ex : знает ?b . ?a ex : создано ?c . ?b ex : создано ?c . ?b ex : возраст ? д . ФИЛЬТР ( ?d < 30 ) }
скомпилировал бы в
[ GraphStep ( [] , vertex ), MatchStep ( AND , [[ MatchStartStep ( a ), LabelStep , IsStep ( eq ( Person )), MatchEndStep ] , [ MatchStartStep ( a ), VertexStep ( OUT , [ знает ] , вершина ), MatchEndStep ( b ) ] , [ MatchStartStep ( a ), VertexStep ( OUT , [ создано ] , вершина ), MatchEndStep ( c ) ] , [ MatchStartStep ( b ), VertexStep ( OUT , [ создано ] , вершина ), MatchEndStep ( c ) ] , [ MatchStartStep ( b ), PropertiesStep ( [ age ] , value ), MatchEndStep ( d ) ] , [ MatchStartStep ( d ), IsStep ( gt ( 30 )), MatchEndStep ]] ), SelectStep ( [ a , b , c ] ) ] .
В Gremlin-Java8 приведенный выше запрос SPARQL будет представлен, как показано ниже, и скомпилирован в идентичную последовательность шагов Gremlin (т. е. обход).
г . В (). match ( as ( "a" ). label (). is ( "person" ), as ( "a" ). out ( "знает" ). as ( "b" ), as ( "a" ). out ( « создано» ), как ( « c » ), как ( « b» ) , как ( « создано » ) , как ( « b » ) . d" ), как ( "d" ). есть ( gt ( 30 )). выбрать ( «а» , «б» , «в» )
Машина обхода графа Gremlin может выполняться на одной машине или в вычислительном кластере из нескольких машин. Агностицизм выполнения позволяет Gremlin работать как с графовыми базами данных (OLTP), так и с графовыми процессорами (OLAP).