Да, это реально, это, наконец, здесь! Долгожданное продолжение вступительной статьи уже здесь, как раз к новому году!
В первой статье мы узнали о графовых базах данных, их различиях и преимуществах по сравнению с традиционными базами данных и о Neo4j. В этой статье мы собираемся установить Neo4j, интегрировать и оценивать драгоценные камни, перечисленные в первой части этой серии.
Сценарий, с которым мы собираемся работать, является продолжением простой идеи из первой статьи , примера социальной сети, которая способна производить обходные запросы, такие как «учитывая тот факт, что Боб мой друг, дай мне всех друзей, которые друг друга друг друга Боба ».
Установка Neo4j
Установка сервера Neo4j довольно проста. Вы можете скачать автономный сервер здесь или установить его с помощью Homebrew . Для этой статьи и для простоты мы собираемся использовать Homebrew:
$ brew update && brew install neo4j
После завершения установки доступны следующие команды:
Запустите сервер:
$ neo4j start
Остановите сервер:
$ neo4j stop
Откройте webadmin, который позволяет вам манипулировать данными с помощью веб-интерфейса:
$ open http://localhost:7474/webadmin/
Использование Neo4j с Ruby
Теперь, когда сервер установлен, следующим шагом будет интеграция с Neo4j. Как уже упоминалось во вступительной статье , мы будем оценивать драгоценные камни: Neo4j.rb , Neoid и Neography .
Neo4j.rb
Что такое Neo4j.rb , по мнению автора:
Вы можете думать о Neo4j как о высокопроизводительном графическом движке со всеми функциями зрелой и надежной базы данных. Программист работает с объектно-ориентированной, гибкой сетевой структурой, а не со строгими и статичными таблицами, но при этом пользуется всеми преимуществами полностью транзакционной базы данных корпоративного уровня.
Этот драгоценный камень действительно обширный, и я призываю вас изучить все его возможности. В этой статье я остановлюсь только на одном аспекте: узлах и отношениях.
Предпосылки
Этот драгоценный камень требует JRuby . Если вы используете RVM , вы можете легко установить его с помощью:
$ rvm install jruby
Затем переключитесь на JRuby, выполнив:
$ rvm use jruby
Установка Neo4j.rb
Вы можете добавить neo4j
$ gem 'neo4j'
И запустите Bundler:
$ bundle
Или установить вручную с помощью:
$ gem install neo4j
интеграция
Прежде чем мы сможем создать наши узлы и наши отношения, нам нужно, чтобы наш код был частью транзакции. Это необходимо, потому что Neo4j имеет транзакции ACID .
Поскольку наш пример относительно прост, мы собираемся инкапсулировать наш код для запуска внутри блока Neo4j :: Transaction :
require 'rubygems'
require 'bundler/setup'
require 'neo4j'
Neo4j::Transaction.run do
# our code here
end
Следующее, что мы собираемся сделать, это создать несколько узлов, которые будут представлять наших пользователей:
require 'rubygems'
require 'bundler/setup'
require 'neo4j'
Neo4j::Transaction.run do
me = Neo4j::Node.new(:name => 'Me', :age => 31)
bob = Neo4j::Node.new(:name => 'Bob', :age => 29)
mark = Neo4j::Node.new(:name => 'Mark', :age => 34)
mary = Neo4j::Node.new(:name => 'Mary', :age => 32)
john = Neo4j::Node.new(:name => 'John', :age => 33)
andy = Neo4j::Node.new(:name => 'Andy', :age => 31)
end
Далее мы создаем дружеские отношения между пользователями:
require 'rubygems'
require 'bundler/setup'
require 'neo4j'
Neo4j::Transaction.run do
me = Neo4j::Node.new(:name => 'Me', :age => 31)
bob = Neo4j::Node.new(:name => 'Bob', :age => 29)
mark = Neo4j::Node.new(:name => 'Mark', :age => 34)
mary = Neo4j::Node.new(:name => 'Mary', :age => 32)
john = Neo4j::Node.new(:name => 'John', :age => 33)
andy = Neo4j::Node.new(:name => 'Andy', :age => 31)
me.both(:friends) << bob
bob.both(:friends) << mark
mark.both(:friends) << mary
mary.both(:friends) << john
john.both(:friends) << andy
end
Вот как дружеские отношения между пользователями (узлами) в настоящее время представлены:
Последний шаг в этом примере — пройти через узлы и найти все дружеские отношения от Меня до Энди .
Полный пример выглядит так:
require 'rubygems'
require 'bundler/setup'
require 'neo4j'
Neo4j::Transaction.run do
me = Neo4j::Node.new(:name => 'Me', :age => 31)
bob = Neo4j::Node.new(:name => 'Bob', :age => 29)
mark = Neo4j::Node.new(:name => 'Mark', :age => 34)
mary = Neo4j::Node.new(:name => 'Mary', :age => 32)
john = Neo4j::Node.new(:name => 'John', :age => 33)
andy = Neo4j::Node.new(:name => 'Andy', :age => 31)
me.both(:friends) << bob
bob.both(:friends) << mark
mark.both(:friends) << mary
mary.both(:friends) << john
john.both(:friends) << andy puts me.outgoing(:friends).depth(5).map{|node| node[:name]}.join(" => ")
end
Запуск примера
Давайте запустим наш пример и посмотрим, получим ли мы ожидаемый результат.
$ ruby neo4j_example.rb
И, как и ожидалось, мы получаем следующий вывод:
Me => Bob => Mark => Mary => John => Andy
Neography
Что такое неография , по мнению автора:
Neography — это тонкая оболочка Ruby для Neo4j Rest API
Этот драгоценный камень — отличная альтернатива, если вы не хотите использовать JRuby со своим приложением, но все же хотите использовать Neo4j. Однако у него есть свои ограничения, и автор рекомендует использовать Neo4j.rb , чтобы иметь доступ ко всем возможностям Neo4j.
Установка Неографии
Вы можете добавить neography
gem 'neography'
И запустите Bundler:
$ bundle
Или установить вручную с помощью:
$ gem install neography
интеграция
Давайте начнем с создания нескольких пользовательских узлов:
me = Neography::Node.create(name: 'Me', age: 31)
bob = Neography::Node.create(name: 'Bob', age: 29)
mark = Neography::Node.create(name: 'Mark', age: 34)
mary = Neography::Node.create(name: 'Mary', age: 32)
john = Neography::Node.create(name: 'John', age: 33)
andy = Neography::Node.create(name: 'Andy', age: 31)
Теперь давайте создадим дружеские отношения между узлами:
me.both(:friends) << bob
bob.both(:friends) << mark
mark.both(:friends) << mary
mary.both(:friends) << john
john.both(:friends) << andy
Визуально вот как представлены отношения дружбы:
Далее мы пересекаем узлы, чтобы найти все дружеские отношения от Меня до Энди :
me.all_simple_paths_to(andy).incoming(:friends).depth(5).nodes.each do |node|
puts node.map{|n| n.name }.join(' => ')
end
И полный пример выглядит так:
require 'rubygems'
require 'neography'
me = Neography::Node.create(name: 'Me', age: 31)
bob = Neography::Node.create(name: 'Bob', age: 29)
mark = Neography::Node.create(name: 'Mark', age: 34)
mary = Neography::Node.create(name: 'Mary', age: 32)
john = Neography::Node.create(name: 'John', age: 33)
andy = Neography::Node.create(name: 'Andy', age: 31)
me.both(:friends) << bob
bob.both(:friends) << mark
mark.both(:friends) << mary
mary.both(:friends) << john
john.both(:friends) << andy me.all_simple_paths_to(andy).incoming(:friends).depth(5).nodes.each do |node| puts node.map{|n| n.name }.join(' => ')
end
Запуск сервера
Чтобы выполнить завершенный пример, нам сначала нужно инициализировать сервер Neo4j. Первый вариант — запустить сервер, который мы установили ранее с помощью Homebrew:
$ neo4j start
Другой вариант — использовать грабли Neography для установки / запуска / остановки / перезапуска сервера. Для этого просто добавьте следующую строку в ваш Rakefile:
require 'neography/tasks'
И вам будут доступны следующие задачи:
rake neo4j:install[edition,version] # Install Neo4j
rake neo4j:reset_yes_i_am_sure # Reset the Neo4j Server
rake neo4j:restart # Restart the Neo4j Server
rake neo4j:start # Start the Neo4j Server
rake neo4j:stop # Stop the Neo4j Server
Запуск примера
Когда мы запустим пример:
$ ruby neography_example.rb
Мы получаем следующий вывод:
Me => Bob => Mark => Mary => John => Andy
Это показывает все пройденные узлы от Меня до Энди , как мы и ожидали.
Neoid
Что такое Неоид , по мнению автора:
Сделайте ваши ActiveRecords сохраненными и доступными для поиска в графовой базе данных Neo4j, чтобы делать быстрые графовые запросы, которые MySQL будет сканировать при их выполнении. Neoid to Neo4j — это как Sunspot для Solr. Вы получаете преимущества скорости Neo4j, сохраняя свою схему в своей простой старой СУБД.
Предпосылки
Поскольку Neoid работает с ActiveRecord, давайте начнем с создания простого приложения на Rails:
$ rails new neoid_example -S -J
Установка Неоид
Вы можете добавить neoid
gem 'neoid', git: 'git://github.com/elado/neoid.git'
И запустите Bundler:
$ bundle
Запуск сервера
Поскольку Neoid работает на Neography , у нас есть те же опции, что и у серверов Neography. Мы можем либо запустить автономный сервер, либо включить грабли, предоставляемые Neography:
Запуск автономного сервера:
$ neo4j start
Чтобы использовать rake-задачи Neography для установки / запуска / остановки / перезапуска сервера, просто добавьте следующую строку в ваш Rakefile:
require 'neography/tasks'
И вам будут доступны следующие задачи:
rake neo4j:install[edition,version] # Install Neo4j
rake neo4j:reset_yes_i_am_sure # Reset the Neo4j Server
rake neo4j:restart # Restart the Neo4j Server
rake neo4j:start # Start the Neo4j Server
rake neo4j:stop # Stop the Neo4j Server
интеграция
Теперь, когда у нас есть базовое приложение rails, следующим шагом будет создание двух моделей: User и Friendship . Первый будет содержать несколько основных атрибутов, таких как имя и возраст. Последний будет поддерживать дружеские отношения между пользователями.
Генерация пользовательской модели:
$ rails g model user
Генерация модели дружбы:
$ rails g model friendship
Далее нам нужно обновить миграцию для обеих моделей:
# User migration
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :age
t.timestamps
end
end
end
# Friendship migration
class CreateFriendships < ActiveRecord::Migration
def change
create_table :friendships do |t|
t.integer :user_id
t.integer :friend_id
t.timestamps
end
end
end
Теперь нам нужно добавить пользовательский инициализатор, который содержит конфигурацию, необходимую для Neoid. Автор рекомендует создать инициализатор в config/initializers/01_neo4j.rb
require('neography') unless defined?(Neography)
ENV["NEO4J_URL"] ||= "http://localhost:7474"
uri = URI.parse(ENV["NEO4J_URL"])
neo = Neography::Rest.new(uri.to_s)
Neography.configure do |c|
c.server = uri.host
c.port = uri.port
if uri.user && uri.password
c.authentication = 'basic'
c.username = uri.user
c.password = uri.password
end
end
Neoid.db = neo
Следующим шагом будет обновление модели User для включения Neoid и установки ее в качестве Node и одной ассоциации has_many :
class User < ActiveRecord::Base
include Neoid::Node
attr_accessible :name, :age
has_many :friends, class_name: Friendship
neoidable do |c|
c.field :name
end
end
Теперь нам нужно обновить нашу модель Дружбы, включив в нее Neoid, и установить ее как Relationship , а также пару ассоциацийочных принадлежностей:
class Friendship < ActiveRecord::Base
include Neoid::Relationship
attr_accessible :friend
belongs_to :user
belongs_to :friend, class_name: User
neoidable do |c|
c.relationship start_node: :user, end_node: :friend, type: :friends
end
class << self
def create_both(user, friend)
user.friends.create(friend: friend)
friend.friends.create(friend: user)
end
end
end
Для последнего шага этой настройки нам просто нужно запустить миграцию:
$ rake db:migrate
Теперь, когда настройка завершена, нам нужно добавить некоторые данные. Давайте откроем консоль rails и добавим несколько пользователей и несколько друзей.
Здесь мы создаем шесть пользователей.
me = User.create(name: 'Me', age: 31)
bob = User.create(name: 'Bob', age: 29)
mark = User.create(name: 'Mark', age: 34)
mary = User.create(name: 'Mary', age: 32)
john = User.create(name: 'John', age: 33)
andy = User.create(name: 'Andy', age: 31)
Далее нам нужно создать дружеские отношения между пользователями:
Friendship.create_both(me, bob)
Friendship.create_both(bob, mark)
Friendship.create_both(mark, mary)
Friendship.create_both(mary, john)
Friendship.create_both(john, andy)
Используя веб-интерфейс Neo4j, мы можем видеть, как взаимосвязи визуально представлены:
Запуск примера
Получив данные, нам нужно пройтись и найти всех друзей между мной и Энди . Для этого давайте обновим нашу модель User и добавим следующий метод экземпляра:
def all_friends_to(user)
neo_node.all_simple_paths_to(user.neo_node).incoming(:friends).depth(5).nodes.each do |node|
puts node.map{|n| n.name }.join(' => ')
end
end
Затем перезапустите консоль rails и выполните следующее:
me = User.first
andy = User.last
me.all_friends_to(andy)
=> "Me => Bob => Mark => Mary => John => Andy"
Как мы видим, это показывает все пройденные узлы от Меня до Энди , как и ожидалось.
Вывод
В этой статье демонстрируется, как установить Neo4j, и как понять, как интегрировать его с приложением Ruby / Rails, используя различные доступные решения. Несмотря на то, что приведенные здесь примеры едва касаются поверхности Neo4j, он, надеюсь, даст вам достаточно знаний и любопытства, чтобы начать интегрировать его в свои собственные проекты.
Надеюсь, вам понравилось читать эту статью так же, как мне понравилось ее писать. С новым годом!