Gremlin — это предметно-ориентированный язык для обхода графов свойств. Neo4j — это одна из баз данных, которая может говорить на языке гремлинов, и, как и обещал, я покажу вам, как вы можете использовать его для реализации рекомендаций друзей, а также степени разделения .
Мы можем отправить любой скрипт gremlin в Neo4j через REST API и neography с помощью команды execute_script. Давайте реализуем ideas_for, чтобы он отправлял на сервер скрипт gremlin:
def suggestions_for(node) node_id = node["self"].split('/').last @neo.execute_script("g.v(node_id). in('friends'). in('friends'). dedup. filter{it != g.v(node_id)}. name", {:node_id => node_id}) end puts "Johnathan should become friends with #{suggestions_for(johnathan).join(', ')}" # RESULT # Johnathan should become friends with Mary, Phil
Давайте пройдемся по шагам гремлина :
g
это наш график
v(node_id)
вершина с идентификатором, полученным из node_id (который будет передан в качестве параметра позже). В гремлине узел — это вершина, а отношение — это ребро.
in('friends')
говорит Гремлину, что мы хотим пересечь входящие отношения типа «друзья», и мы хотим сделать это дважды, так как собираемся завести друзей друзей.
dedup
удаляет дубликаты узлов, которые мы нашли по пути … вы знаете популярных детей.
name
захватывает свойство name найденных узлов. Вы хотите параметризовать свой скрипт, когда это возможно, чтобы избежать повторного анализа и повысить производительность.
Как насчет степени разделения?
def degrees_of_separation(start_node, destination_node) start_node_id = start_node["self"].split('/').last destination_node_id = destination_node["self"].split('/').last @neo.execute_script("g.v(start_node_id). as('x'). in.loop('x'){it.loops <= 4 & it.object.id != destination_node_id}. simplePath. filter{it.id == destination_node_id}. paths{it.name}", {:start_node_id => start_node_id, :destination_node_id => destination_node_id }) end degrees_of_separation(johnathan, mary).each do |path| puts "#{(path.size - 1 )} degrees: " + path.join(' => friends => ') end # RESULT # 3 degrees: Johnathan => friends => Mark => friends => Phil => friends => Mary # 2 degrees: Johnathan => friends => Mark => friends => Mary
Этот немного сложнее. Мы снова начинаем с нашего графика
g
затем перейдите к начальному узлу (или вершине)
v(start_node_id)
мы будем называть этот шаг х с
as('x')
команда, потому что мы хотим вернуться сюда позже.
in.loop('x')
говорит Гремлину пересечь входящие отношения и продолжать цикл, но вернуться к x, когда следующее условие становится ложным. Гремлин отслеживает количество пройденных вами циклов, и здесь мы говорим, что нужно остановиться на 4
it.loops <= 4
и остановимся, если мы доберемся до пункта назначения по пути
it.object.id != destination_node_id}
Мы избегаем повторения элементов в пути с
simplePath
и мы фильтруем результаты, которые заканчиваются в нашем узле назначения с
filter{it.id == destination_node_id}
и получить имена узлов в пути с
paths{it.name}
Затем мы передаем наши параметры
{:start_node_id => start_node_id, :destination_node_id => destination_node_id }
Гремлин очень мощный и ему помогает весь стек Tinkerpop . Вам понадобится некоторое время и немного чего-то, чтобы привести вас в правильное состояние ума, но если вы сможете справиться с этим, то чтение вики-гремлина расширит ваш кругозор. Если вы предпочитаете смотреть, а не читать, это видео даст вам довольно хорошее представление о языке Gremlin.