Read more

Using Solr with Sunspot

Thomas Eisenbarth
January 24, 2012Software engineer at makandra GmbH

This describes all the steps you'll need to get Solr up and running for your project using the Sunspot gem Show archive.org snapshot .

Prepare Sunspot on your development machine

Illustration online protection

Rails professionals since 2007

Our laser focus on a single technology has made us a leader in this space. Need help?

  • We build a solid first version of your product
  • We train your development team
  • We rescue your project in trouble
Read more Show archive.org snapshot

What you want in your Gemfile:

gem 'sunspot_rails'
gem 'sunspot_solr'
gem 'progress_bar' # for sunspot:solr:reindex

Now define what should be indexed within Solr from your ActiveRecord models, e.g.,

class Article << ActiveRecord::Base

  searchable do
    text :title
  end

end

will make the attribute 'title' of your Article model available for Solr search.
Before using Solr you have to start your local instace by running Sunspot's rake task:

bundle exec rake sunspot:solr:start

Now prepare Solr's index by re-indexing all existing records by running

Article.reindex

from within a console. This will take batches of 50 records and index them into Solr.
Afterwards, you can use Solr by calling

Article.search {
  fulltext(title)
  paginate(:per_page => limit)
}

Now look at http://sunspot.github.com/docs/ Show archive.org snapshot to learn about all the possibilities of Sunspot.

Overwrite Sunspots' search method

In case you already have a static method search (because you use our search_trait) alias the search method to search_solr

singleton_class.class_eval do
  alias_method :search_solr, :search
end

directly before you insert the trait (look for does 'searchable') where search will be overwritten again.

You can access the Solr search via Article.search_solr {...} now while the old search method is still available.

Catch Sunspot exceptions (Errno::ECONNREFUSED or Timeout::Error)

Finally you might to be smart in case your Solr server is unreachable (crashed, network unreachable, etc.). Even if you decide not to present a cool error message to your user (what we do below) but throw another exception, it might help to be a bit more precise about the fact that it was the connection to Solr that failed. Otherwise you'll see a Errno::ECONNREFUSED in your exception mail and have to look at your code to find out at which point the exception was thrown.

def self.search_solr_with_exception_handling(*types, &block)
  begin
    search_solr_without_exception_handling(*types, &block)
  rescue Errno::ECONNREFUSED, Timeout::Error => e
    message = "Verbindung zu Solr nicht möglich: #{e.message}"
    logger.error message
    raise Exception.new message
  end
end

 singleton_class.class_eval do
   alias_method :search_solr, :search
   alias_method_chain :search_solr, :exception_handling
 end

Prepare Solr for production

Usually you will not use Sunspot's rake tasks to fire up Solr on your production machines but run it on top of some Java application server, e.g., Tomcat.
So tell your SysOp team that you'll need Solr on staging and production, on Ubuntu the solr-common will provide what you need.

First of all you should provide Solr with the correct schema information of Sunspot. Look for schema.xml that could live within /etc/solr/conf/. You should automate the task of putting schema.xml to the correct place during deployment or point Solr to the configuration within your application code, e.g., by sym-linking /etc/solr/conf/schema.xml to your application directory. Keep in mind that you will have to restart Solr when schema.xml changes.

You have to change config/sunspot.yml to point to your production Solr host and port. If Solr is installed on the same machine that your application runs on, use that for Tomcat

production:
  solr:
    hostname: localhost
    port: 8080
    log_level: WARNING

Remember to copy the configuration for staging environment.

Thomas Eisenbarth
January 24, 2012Software engineer at makandra GmbH
Posted by Thomas Eisenbarth to makandra dev (2012-01-24 15:21)