Skip to content

Commit

Permalink
Rails integration and rake tasks.
Browse files Browse the repository at this point in the history
* Updated the integration with Rails applications.
* Updated the README to reflect new changes.
* Created Bigindex rake tasks for rebuilding/dropping the index.
  • Loading branch information
greglu committed Oct 27, 2009
1 parent 91729a7 commit 139b1f9
Show file tree
Hide file tree
Showing 8 changed files with 267 additions and 86 deletions.
48 changes: 41 additions & 7 deletions README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,28 @@ This should be used in conjunction with BigRecord in order to provide a more com

== Installation

(1) Download and install Solr. Take a note of the url that solr is running on.
(1) Install the Solr search server into your Rails application with the bigindex-solr package [http://github.com/openplaces/bigindex-solr]. Alternatively, if you want to setup your own Solr server, you'll need to read the [Solr schema] section below and take note of the Solr url to connect to.

(2) In your Rails application, add Bigindex as a gem to your config/environment.rb file:

config.gem "bigindex", :source => "http://gemcutter.org"

and run the following rake task to install all the gems listed for your Rails app:

[sudo] rake gems:install

(3) Bootstrap Bigindex into your Rails application:
(3) Add the following line to the bottom of your RAILS_ROOT/Rakefile

require 'bigindex/tasks'

=== NOTE: Skip steps (4) and (5) if you're using the bigindex-solr package.

(4) Create a Bigindex config file for your Rails application

rake bigindex:generate_config

(5) Modify the config file config/bigindex.yml[.sample] to correspond to your Solr server.

script/generate bigindex

(4) Modify the config file config/bigindex.yml[.sample] to correspond to your Solr server.

== Getting Started

Expand All @@ -43,11 +50,38 @@ Modify your Ruby class/model similarly to the following:

BigIndex will then override the default Model.find() method to pass through the indexer first. Model.find() will also accept the option {:bypass_index => true}, which bypasses the indexed #find method and dispatches it to the original Model.find() method, e.g. Model.find(:all, :bypass_index => true). Alternatively, you can use Model.find_without_index(:all) for the same functionality.

== Rebuilding your index

Once you have your models setup with Bigindex, you will need to rebuild the index. To do so, run the rake task:

rake bigindex:rebuild_index

This rake task accepts the following options:
* BATCH_SIZE: Defaults to 100. For each model, it will batch process this number of records at a time.
* CLEAR: Defaults to true. Before rebuilding the model, drop the current index before rebuilding it.
* OPTIMIZE: Defaults to true. A Solr option to optimize the index after it's created.

An example usage is:

rake bigindex:rebuild_index BATCH_SIZE=150 CLEAR=true OPTIMIZE=true

== Drop current index

To drop the index of your current environment, use:

rake bigindex:drop_index

This will drop the index of any model in your RAILS_ROOT/app/models folder that includes BigIndex::Resource. Be very careful with this task!

== Solr schema

Bigindex has a defined schema to use with Solr. If you need to set up Solr yourself, you'll need to either use the schema.xml defined in this project, or create a merged version of it with your own.

== License

Bigindex is released under the MIT license.

== Contributions
== Credit

Bigindex was derived from the work of Data Mapper and parts of acts_as_solr.

Expand Down
17 changes: 0 additions & 17 deletions generators/bigindex/bigindex_generator.rb

This file was deleted.

3 changes: 0 additions & 3 deletions generators/bigindex/templates/bigindex.rake

This file was deleted.

105 changes: 47 additions & 58 deletions lib/big_index/resource.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@

module BigIndex
module Resource

def self.included(model)
model.extend ClassMethods if defined?(ClassMethods)
model.const_set('Resource', self) unless model.const_defined?('Resource')

model.class_eval do
include InstanceMethods
extend ClassMethods

@indexed = true

@index_configuration = {
:fields => [],
:additional_fields => nil,
Expand Down Expand Up @@ -41,8 +36,6 @@ class << self
end
end

alias model class

module ClassMethods

def default_repository_name
Expand Down Expand Up @@ -153,9 +146,9 @@ def rebuild_index(options={}, finder_options={})
items_processed = 0
loop = 0

# Depending on whether the model has a scan or find method, use that.
# scan is from Bigrecord models, and find is from Activerecord.
if self.respond_to?(:scan)
# TODO: This scan method doesn't always exist (in the case of ActiveRecord).
# This will need to be removed.
self.scan(finder_options) do |r|
items_processed += 1
buffer << r
Expand Down Expand Up @@ -264,23 +257,6 @@ def index(*params, &block)
define_finder index_field[:finder_name]
end

def add_index_field(index_field)
configuration = @index_configuration
if configuration[:fields]
unless configuration[:fields].include?(index_field)
configuration[:fields] << index_field
else
return
end
else
configuration[:fields] = [index_field]
end

define_method("#{index_field.field_name}_for_index") do
index_field.block ? index_field.block.call(self) : self.send(index_field.field_name.to_sym)
end
end

##
#
# Class #find method
Expand Down Expand Up @@ -382,7 +358,24 @@ def validate_index_find_options(options) #:nodoc:
options.assert_valid_keys(INDEX_FIND_OPTIONS)
end

private
private

def add_index_field(index_field)
configuration = @index_configuration
if configuration[:fields]
unless configuration[:fields].include?(index_field)
configuration[:fields] << index_field
else
return
end
else
configuration[:fields] = [index_field]
end

define_method("#{index_field.field_name}_for_index") do
index_field.block ? index_field.block.call(self) : self.send(index_field.field_name.to_sym)
end
end

##
#
Expand Down Expand Up @@ -418,45 +411,41 @@ def self.find_by_#{finder_name}(user_query, options={})
end # module ClassMethods


module InstanceMethods

def index_adapter
self.class.index_adapter
end
def index_adapter
self.class.index_adapter
end

def index_configuration
self.class.index_configuration
end
def index_configuration
self.class.index_configuration
end

def indexed?
self.class.indexed?
end
def indexed?
self.class.indexed?
end

def record_id
self.id
end
def record_id
self.id
end

def index_type
self.class.index_type
end
def index_type
self.class.index_type
end

def index_id
"#{index_type}:#{record_id}"
end
def index_id
"#{index_type}:#{record_id}"
end

def index_save
unless self.class.index_disabled || index_configuration[:auto_save] == false
index_adapter.index_save(self)
end
def index_save
unless self.class.index_disabled || index_configuration[:auto_save] == false
index_adapter.index_save(self)
end
end

def index_destroy
unless index_configuration[:auto_save] == false
index_adapter.index_destroy(self)
end
def index_destroy
unless index_configuration[:auto_save] == false
index_adapter.index_destroy(self)
end

end # module InstanceMethods
end

end # module Resource
end # module BigIndex
3 changes: 3 additions & 0 deletions lib/big_index/tasks.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
require 'rake' unless defined? Rake

Dir["#{File.join(File.dirname(__FILE__),"..")}/tasks/*.rake"].sort.each { |ext| load ext }
50 changes: 50 additions & 0 deletions lib/tasks/bigindex.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
namespace :bigindex do

desc 'Generates a bigindex.yml config file and places it into your RAILS_ROOT/config folder. Creates bigindex.yml.sample if the file already exists.'
task :generate_config do
require File.join(File.dirname(__FILE__), "..", "..", "install.rb")
end

desc 'Rebuilds the index based on the models in your RAILS_ROOT/app/models folder that include BigIndex::Resource'
task :rebuild_index => :environment do
models = Dir.glob("#{RAILS_ROOT}/app/models/*.rb").map { |path| File.basename(path, ".rb").camelize.constantize }

# Read in the rake options and set them to defaults if needed
batch_size = ENV['BATCH_SIZE'].to_i.nonzero? || 100
clear_first = env_to_bool('CLEAR', true)
optimize = env_to_bool('OPTIMIZE', true)

# Grab all the models that are indexable
models = models.select { |m| m.respond_to?(:indexed?) && m.indexed? }

# Setting the options for the rebuild_index method
options = {:batch_size => batch_size, :drop => clear_first, :optimize => optimize}
finder_options = {:batch_size => batch_size}

models.each do |model|
model.rebuild_index(options, finder_options)
end
end

desc 'Drops the index of all the models in your Rails app that include BigIndex::Resource'
task :drop_index => :environment do
models = Dir.glob("#{RAILS_ROOT}/app/models/*.rb").map { |path| File.basename(path, ".rb").camelize.constantize }

# Grab all the models that are indexable
models = models.select { |m| m.respond_to?(:indexed?) && m.indexed? }

models.each do |model|
model.drop_index
end
end

def env_to_bool(env, default)
env = ENV[env] || ''
case env
when /^true$/i then true
when /^false$/i then false
else default
end
end

end
Loading

0 comments on commit 139b1f9

Please sign in to comment.