Статьи

Использование Гремлин с неографией

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.