Skip to content
Andreas Ronge edited this page Jun 7, 2014 · 57 revisions

The Neo4j V3 is a complete rewrite and will work on MRI since you can run it using either the Neo4j server or embedded API. The Neo4j embedded API is only available if running on JRuby.

Neo4j-core

Please read the neo4j-core README. The neo4j gem uses the neo4j-core gem. Neo4j gem provides an active model compliant api which means it will work great together with rails. Neo4j-core gem contains many useful methods and classes.

Usage from Ruby

Installation of Neo4j Server and start server:

rake neo4j:install[community-2.0.2]
rake neo4j:start

Example, Open a session to the neo4j server database (in IRB for example)

  Neo4j::Session.open(:server_db, "http://localhost:7474")

After you have created a session you can now use the database, see below.

Usage from JRuby

On JRuby you can access the database in two different ways: using the embedded db or the server db.

Example, Open a session to the neo4j embedded database (running in the same JVM)

  session = Neo4j::Session.open(:embedded_db, '/folder/db')
  session.start

Usage with a remote Server

Example of a rails config/application.rb file:

config.neo4j.session_options = { basic_auth: { username: 'foo', password: 'bar'} } 
config.neo4j.session_type = :server_db 
config.neo4j.session_path = 'http://localhost:7474'

All options from HTTParty are available. For more Information see http://rdoc.info/github/jnunemaker/httparty/HTTParty/ClassMethods

See https://gist.github.com/andreasronge/11189170 how to configure the Neo4j::Session with basic authentication from a none rails application.

Usage from heroku

Add a Neo4j db to your application:

heroku addons:add graphenedb

Example of a rails config/application.rb file:

config.neo4j.session_type = :server_db 
config.neo4j.session_path = ENV["GRAPHENEDB_URL"] || 'http://localhost:7474'

Usage from Rails

 rails new myapp -m http://andreasronge.github.com/neo4j/neo4j.rb -O
 cd myapp
 rake neo4j:install[community-2.0.2]
 rake neo4j:start

 rails generate scaffold User name:string email:string
 rails s
 open http://localhost:3000/users

Or manually modify the rails config file config/application.rb:

require 'neo4j/railtie'

module Blog
  class Application < Rails::Application
     # This is for embedded db, only available from JRuby
     #config.neo4j.session_type = :embedded_db # or server_db
     #config.neo4j.session_path = File.expand_path('neo4j-db', Rails.root) # or http://localhost:port
  end
end

You can skip Active Record by using the -O flag when generating the rails project.

Property

All properties for Neo4j::ActiveNode objects must be declared (unlike neo4j-core nodes). Properties are declared using the property method which is the same as attribute from the active_attr gem.

Example:

class Post
  include Neo4j::ActiveNode
  property :title
  property :text, default: 'bla bla bla'
  property :score, type: Integer, default: 0

  validates :title, :presence => true
  validates :score, numericality: { only_integer: true }

  index :title

  before_save do
    self.score = score * 100
  end

  has_n :friends
end

Properties can be indexed using the index method, see example above.

Callbacks

Implements like Active Records the following callback hooks:

  • initialize
  • find
  • save
  • create
  • update
  • destroy

created_at, updated_at

See http://neo4j.rubyforge.org/classes/Neo4j/Rails/Timestamps.html

class Blog
  include Neo4j::ActiveNode
  has_n(:comments, on_updated: set_timestamp, :on_created: set_timestamp)
  property :updated_at  # will automatically be set when model changes
end

User defined callbacks for relationships:

class Blog
  include Neo4j::ActiveNode
  has_n(:comments, on_updated :handle_update_rel, on_created: :handle_create_rel)
  property :updated_at  # will automatically be set when model changes

  def handle_update_rel(relationship, changed_props)
   # this method is called when a relationship is changed
  end

  def handle_create_rel(relationship, changed_props, other_node)
   # this method is called when a relationship is created
  end

end

The reason why we don't want active model compliant relationship objects is because the code is very complex, and maybe not much used.

Validation

Support the Active Model validation, such as:

  • validates :age, presence: true
  • validates_uniqueness_of :name, :scope => :adult

Query

The Neo4j::ActiveNode module has two query methods: find and all, which accepts the same arguments as Neo4j::Session#query in neo4j-core

all

# Find all blog models
Blog.all

# Find all blog models with the exact title: neo4j
Blog.all(conditions: title: "neo4j")

find

Find returns one ruby object or nil if none was found.

# find one blog node having the exact title 'neo4j.rb v3.0':
Blog.find(conditions: title: "neo4j")

# Example, find by id
Blog.find(4242)

Orm_Adapter

You can also use the orm_adapter API, by calling #to_adapter on your class. See the API, https://github.com/ianwhite/orm_adapter

Where, Order, Fluent API - NOT IMPLEMENTED

Not Implemented Yet

# Simple helper for the cypher where clause, http://docs.neo4j.org/chunked/stable/query-where.html
Blog.where(:n, 'n.name = {name} XOR (n.age < {age} AND n.name = "Tobias") OR NOT (n.name = "Tobias" OR
  n.name={name}', name: 'Peter', age: 30)

# Order
Blog.order(created_at: :desc)

# Chaining methods
Blog.where(:n, 'n.name = {name}', name: 'Andreas').order(:name, text: :asc)

Match

Not Implemented Yet Not sure we should impl. this:

# Return all blogs with comments, same as 'MATCH (n:Blog) -[:comments]->(comment) RETURN n' 
Blog.match(outgoing: :comments)

# Find all comments for blogs made by user andreas
Blog.comments(user: 'andreas')

# Find all comments made for blogs made last day
Blog.comments_rels(created_at: [Time.now - 1.day ... Time.now])
# TODO more possibilities to explore

Can be combined with where and sort

Cypher

Same as in neo4j-core

Relationship

Same as the Neo4j-core API, see https://github.com/andreasronge/neo4j-core

blog.rels(dir: :outgoing, type: :comments)

Declared Relationships

class Blog
  include Neo4j::ActiveNode
  has_n :comments
end
class Comment
  include Neo4j::ActiveNode
  has_one(:belongs_to_blog).from(:comments)
end

comment = Comment.create
blog = Blog.create
comment.belongs_to_blog = blog
blog.comments.to_a #=> includes comment

# or create a relationship object with properties
rel = Blog.comments.create(comment, since: 1994)

Similar to https://github.com/andreasronge/neo4j/wiki/Neo4j%3A%3ARails-Relationships

Inheritance

Index, properties and declared relationships (#has_n and #has_one) are inherited.

Example:

  class Vehicle
    include Neo4j::ActiveNode
    property :name, type: String
    index :name
  end

  class Car < Vehicle
    property :model
    index :model
  end

   bike = Vehicle.create(name: 'bike')
   volvo = Car.create(name: 'volvo', model: 'v60')
   saab = Car.create(name: 'saab', model: '900')

   Car.find(name: 'volvo') # => volvo
   Vehicle.find(name: 'volvo') # => volvo

   Car.find(model: '900') # => saab
   Vehicle.find(model: '900') # => saab

Rails Example

See Rails 4 example: https://github.com/andreasronge/neo4j/tree/3.0/example/blog

Neo4j Core

The neo4j gem uses the neo4j-core gem, see https://github.com/andreasronge/neo4j-core See https://github.com/andreasronge/neo4j-core/tree/3.0

Clone this wiki locally