Skip to content
Permalink
Browse files

Updated IMDB example to use migrations. Updated som documentation. [#111

 state:resolved]  [#108 state:resolved]
  • Loading branch information...
andreas
andreas committed Mar 2, 2010
1 parent 3d3e6bb commit e86e250a2d4cb0debb7a3631c16341341b0be11f
@@ -1491,12 +1491,19 @@ The neo database starts at version 0 by default.

If the code above has been loaded before the neo database starts it will automatically upgrade to version 1 (running all the migrations to the higest migration available).
You can force the neo to go to a specific version by using Neo4j#migrate! method.
For more information see the example/imdb application or the RSpecs.

=== Lazy Migration

The example above can also be run as lazy migration. i.e. perform the upgrade/downgrade when the node is loaded instead of all at once.
The following example demonstrates this feature:

class Person
include Neo4j::NodeMixin
include Neo4j::MigrationMixin # you need to include this in order to use lazy migrations
...
end

Person.migration 1, :split_name do
up do
surname = self[:name].split[0]
@@ -0,0 +1,66 @@
IMDB_FILE = 'data/test-actors.list'

Neo4j.migration 1, "Create DB by parsing IMDB file" do
up do
puts "Migration 1, processing #{IMDB_FILE} file ..."
Neo4j::Transaction.run do
movies = {}
current_actor = nil
actors = 0
no_films = 0

File.open(IMDB_FILE).each_line do |line|
next if line.strip.empty?

tab_items = line.split("\t")

unless tab_items.empty?
if !tab_items[0].empty?
current_actor = Actor.new
current_actor.name = tab_items.shift.strip
actors += 1
# puts "Parse new actor no. #{actors} '#{current_actor.name}'"
end
tab_items.shift

film = tab_items.shift.strip

# already created film ?
movie = movies[film]
if (movie.nil?)
movie = Movie.new
movie.title = film
movie.year = /\((\d+)(\/.)?\)/.match(film)[1]
movies[film] = movie
# puts "Created new film #{film}"
no_films += 1
end

role = tab_items.shift
roleNode = current_actor.acted_in.new(movie)

unless (role.nil?)
role.strip!
# remove []
role.slice!(0)
role.chop!
title, character = role.split('-')
roleNode.title = title.strip unless title.nil?
roleNode.character = character.strip unless character.nil?
end

#puts "Actor: '#{current_actor}' Film '#{film}' Year '#{year}' Title '#{title}' Character '#{character}'"
end
end
puts "created #{actors} actors and #{no_films} films"
end
end

down do
puts "deleting all movies and actors"
Neo4j::Transaction.run do
Actor.all.each {|a| a.del}
Movie.all.each {|m| m.del}
end
end
end
@@ -0,0 +1,21 @@
Neo4j.migration 2, "Index DB" do
up do

puts "Migration 2, Index DB on #{Lucene::Config[:storage_path]}"

Neo4j::Transaction.run do
puts "Creating lucene index ..."
Actor.index :name, :tokenized => true
Actor.update_index
end
# only possible to access and query the index after the transaction commits
end

down do
puts "removing lucene index"
Actor.remove_index :name
# Actor.update_index # maybe nicer way of deleting indexes - hmm, does it work ?
require 'fileutils'
FileUtils.rm_rf Lucene::Config[:storage_path] # quick and dirty way of killing the lucene index
end
end
@@ -1,5 +1,12 @@
Shows how to store and query a neo4j database


1. Download the database type: ./install.sh
2. Create the database: jruby create_neo_db.rb
2. Run the application: jruby find_actors.rb willis

The find_actors.rb uses migration which means that the first time the it is used it will take
a while to process the imdb file and create the index.

Notice that you can play around with migrations by require the 'find_actor' in JIRB and then for example
Neo4j.migrate! 1
which will delete the lucene index (migration number 2)

This file was deleted.

@@ -1,29 +1,54 @@
$LOAD_PATH << File.expand_path(File.dirname(__FILE__) + "/../../lib")
#require "rubygems"
require "rubygems"
require "neo4j"

# we have to configure these before the model is loaded
Lucene::Config[:store_on_file] = true
Lucene::Config[:storage_path] = "tmp/lucene"


require "model"
require "neo4j/extensions/reindexer"

#Neo4j::Config[:storage_path] = DB_NEO_DIR
Neo4j.start
Neo4j::Transaction.run do
Actor.index :name, :tokenized => true
Actor.update_index
end

# have to let the previous transaction finish in order to lucene indexing
# to take place
# Keep lucene index on file system instead of in memory


Neo4j::Transaction.run do
puts "Find all actors named willis"
result = Actor.find(:name => "willis") #, Bruce")
# Load Migrations
# Create Database
require '1_create_neo_db'

puts "Found #{result.size} actors"
result.each {|x| puts x}
# just for fun I have two migrations - first one for importing the database and second for indexing it.
require '2_index_db'

willis = result[0]
puts "#{willis} acted in:"
willis.rels.outgoing.each {|r| puts r.to_s }
def find_actor(name)
Neo4j::Transaction.run do
puts "Find all actors named #{name}"
result = Actor.find(:name => name)

willis.acted_in.each { |movie| puts movie }
puts "Found #{result.size} actors"
result.each {|x| puts "#{x.neo_id}\t#{x}"}
end
end

def find_movies(neo_id)
Neo4j::Transaction.run do
actor = Neo4j.load_node(neo_id)
puts "No actor found with neo id #{neo_id}" if actor.nil?
return if actor.nil?

puts "#{actor} acted in:"
actor.acted_in_rels.each {|r| puts "Movie #{r.end_node.title} title: #{r.title}"}
end
end

Neo4j.start
if (ARGV.size == 1)
find_actor(ARGV[0])
elsif ARGV.size == 2 && ARGV[0] == "-m"
find_movies(ARGV[1])
else
puts "Usage: jruby find_actors.rb [-m] <actor name|actor neo_id>\n\n -m \tfinds the movies for the given actor neo_id"
end

Neo4j.stop
@@ -1,9 +1,3 @@
#DB_NEO_DIR = File.expand_path(File.dirname(__FILE__) + "/db/neo")
#DB_LUCENE_DIR = File.expand_path(File.dirname(__FILE__) + "/db/lucene")

require 'rubygems'
require 'neo4j'
require "neo4j/extensions/reindexer"

class Movie; end

@@ -8,14 +8,18 @@ module Lucene
# as specific configuration for each index (TODO).
# This code is copied from merb-core/config.rb.
#
# Contains three default configurations (Config.defaults)
# * :store_on_file:: default false, which will only keep the index in memory
# * :id_field:: default :id
# * :storage_path:: where the index is kept on file system if stored as a file (instead of just in memory)
#
class Config
class << self
# Returns the hash of default config values for lucene.
#
# ==== Returns
# Hash:: The defaults for the config.
#
# :api: private
def defaults
@defaults ||= {
:store_on_file => false,
@@ -38,7 +42,6 @@ def defaults
# ==== Returns
# nil
#
# :api: public
def use
@configuration ||= {}
yield @configuration
@@ -52,7 +55,6 @@ def use
# key<Object>:: The key to set the parameter for.
# val<Object>:: The value of the parameter.
#
# :api: public
def []=(key, val)
(@configuration ||= setup)[key] = val
end
@@ -63,8 +65,6 @@ def []=(key, val)
# ==== Parameters
# key<Object>:: The key of the config entry value we want
#
# :api: public
#
def [](key)
(@configuration ||= setup)[key]
end
@@ -78,7 +78,6 @@ def [](key)
# ==== Returns
# Object:: The value of the removed entry.
#
# :api: public
def delete(key)
@configuration.delete(key)
end
@@ -90,7 +89,6 @@ def delete(key)
# ==== Returns
# nil
#
# :api: private
def delete_all
@configuration = nil
IndexInfo.delete_all
@@ -107,7 +105,6 @@ def delete_all
# ==== Returns
# Object:: The value of the configuration parameter or the default.
#
# :api: public
def fetch(key, default)
@configuration.fetch(key, default)
end
@@ -117,7 +114,6 @@ def fetch(key, default)
# ==== Returns
# The configuration as a hash.
#
# :api: private
def setup()
@configuration = {}
@configuration.merge!(defaults)
@@ -130,7 +126,6 @@ def setup()
# ==== Returns
# Hash:: The config as a hash.
#
# :api: public
def to_hash
@configuration
end
@@ -140,7 +135,6 @@ def to_hash
# ==== Returns
# String:: The config as YAML.
#
# :api: public
def to_yaml
require "yaml"
@configuration.to_yaml

0 comments on commit e86e250

Please sign in to comment.
You can’t perform that action at this time.