Thursday, October 20, 2011

Solr

Integrating SOLR search into our application. “acts_as_solr” is the name of the plugin(also available as gem).
Install plugin:
script/plugin install git://github.com/mattmatt/acts_as_solr.git

Install gem:
gem install acts_as_solr


Add the below line into your application's configuration file
config.gem "acts_as_solr"

Add this at the end of your Rakefile(only for using gem)
require 'aas_tasks'

After installing gem/plugin, following rake tasks are available to use
rake solr:destroy_index # Remove Solr index
rake solr:reindex # Reindexes data for all ac
ts_as_solr models.
rake solr:start # Starts Solr.
rake solr:stop # Stops Solr.
We can start, stop, reindex, destroy index by using the mentioned rake tasks.


Add the following rake task inside the solr rake file(gems/acts_as_solr/lib/tasks/solr.rake), to start solr in Windows environment.
desc "Starts Solr. on windows . Options accepted: RAILS_ENV=your_env, PORT=XX. Defaults to development if none."
task :start_win do
require "#{File.dirname(__FILE__)}/../../config/solr_environment.rb"
begin
n = Net::HTTP.new('localhost', SOLR_PORT)
n.request_head('/').value

rescue Net::HTTPServerException #responding
puts "Port #{SOLR_PORT} in use" and return

rescue Errno::ECONNREFUSED #not responding
Dir.chdir(SOLR_PATH) do
exec "java -Dsolr.data.dir=solr/data/#{ENV['RAILS_ENV']} -Djetty.port=#{SOLR_PORT} -jar start.jar"
sleep(5)
puts "#{ENV['RAILS_ENV']} Solr started sucessfuly on #{SOLR_PORT}, pid: #{pid}."
end
end
end



Steps to configure solr in our application

1) Starts the solr server
rake solr:start


2) Changes to ActiveRecord model
acts_as_solr - all fields are indexed
class News < ActiveRecord::Base
acts_as_solr :fields => [:title, :content]
end

– specified fields are indexed
We can specify the name of the fields to be used for searching.
Options:
:if => we can supply any condition as string, proc, symbol, method. It will index the record only if condition returns true.

3) Do index/reindex
rake solr:reindex


4) Changes to Controller
News.find_by_solr(query)

query => query is a string representing your query

There are many options available in solr, we can do a refined search by using SOLR.

Problem:
I faced one problem, acts_as_solr :if option is not working with rake task to reindex data. Instead of checking the condition it will simply indexes all the records. But other method like solr_save() checks the condition passed with acts_as_solr definition in model. I have added a patch to check the condition in rake task 'reindex'.

file path: acts_as_solr\lib\class_methods.rb
line no: 200 - 250
method name: rebuild_solr_index
Instead of normal collect,
items.collect! { |content| content.to_solr_doc }


We can use the following code, to filter the records with the condition defined in model and collect the remaining results
items = items.select { |content| content.evaluate_condition_public(content)}
items.collect! { |content| content.to_solr_doc }


After doing the above changes, you can have a correct data in your search results. This is applicable only when we are using acts_as_solr with conditions in model.

acts_as_solr :fields => ["name","description"], :if => proc{|record| record.active?}


Hope, this is useful for someone who is using acts_as_solr with :if option.

Cheers,
Vadivelan

No comments:

Post a Comment