Skip to content

Adding Sunspot search to Rails in 5 minutes or less

Jesse Waites edited this page Feb 3, 2015 · 18 revisions

Installation (Rails 3)

First, add it to your Gemfile:

gem 'sunspot_rails', '~> 1.3.0'

Update your bundle:

$ bundle install

Then generate the config/sunspot.yml:

rails g sunspot_rails:install

And you’re done.

Installation (Rails 2.3)

Simply add the following to your Gemfile:

gem 'sunspot_rails'

Or, if you’re using config.gem statements, first install the gem:

$ sudo gem install sunspot_rails

Then it to your config/environment.rb:

config.gem 'sunspot_rails'

Previous versions of the gem needed to require “sunspot/rails” but this was changed in the 1.2 series of the gem.

Next, run the generator to create the config/sunspot.yml file:

$ script/generate sunspot

To get the Sunspot rake tasks, you’ll need to require the tasks from your app’s Rakefile:

require 'sunspot/rails/tasks'

If you still get

rake sunspot:solr:start
rake aborted!
Don't know how to build task 'sunspot:solr:start'

Then you can copy the rake tasks directly into your project.

cp `bundle show sunspot_solr`/lib/sunspot/solr/tasks.rb lib/tasks/sunspot.rake

Starting a local instance of Solr

Now it’s time to start Solr. Solr is a standalone HTTP server, but Sunspot comes packaged with a copy of it that’s already configured to work with Sunspot; use the rake task to fire it up:

$ rake sunspot:solr:start

The first time you run this command, it will create a solr/ directory in your Rails root. This contains Solr’s configuration, as well as the actual data files for the Solr index. You’ll probably want to add solr/data to your .gitignore. If you later would like to play with Solr’s configuration (e.g., customizing the filter chain for text fields), you’ll find the configuration files in solr/conf. Browse to http://localhost:8982/solr/admin/ to play with Solr.

Model Configuration

For our app, let’s assume we’ve got a Post model, with title and body fields. To set it up for keyword search, we use the searchable method:

class Post < ActiveRecord::Base
  searchable do
    text :title, :default_boost => 2
    text :body
  end
end

Note that text here means that you’re creating a field that’s fulltext-searchable. It’ll be broken apart into individual keywords, and then those keywords will be matched against the words in keyword search queries. There are quite a few other field types, but text is the only one that is searched by keywords. See Setting up classes for search and indexing for more on the different types of fields and how they work.

That :default_boost parameter means that, unless otherwise specified, words matching the :title field should be considered twice as relevant as words matching the :body field.

Now that Sunspot knows how to index the Post model, we need to get the existing data into Solr. Any time a Post is created, updated, or destroyed, Sunspot::Rails will automatically make the change to the index; you only need to do a full reindex if you’ve added or changed a searchable definition for a model.

$ rake sunspot:reindex

Adding search to your application

Sunspot and Solr can do a lot more than simple keyword search, but since we’d like to have you up and running in five minutes, let’s stick with that for now. Let’s assume you’ve got a search form where a user types in some keywords, which submits a :q param to the PostsController#search method.

class PostsController < ApplicationController
  def search
    @search = Post.search(:include => [:comments]) do
      keywords(params[:q])
    end
  end
end

Our @search variable is assigned an object of class Sunspot::Search. Here’s how we’ll work with it in the view in HAML:

.results
  - @search.each_hit_with_result do |hit, post|
    .result
      %h2= h post.title
      %h6== (#{h hit.score})
      %p= h truncate(post.body, :length => 100)
.pagination
  = will_paginate(@search.results)

Here’s how we do it in ERB:

<div class="results">
  <% @search.each_hit_with_result do |hit, post| %>
    <div class="result">
      <h2>
        <%= post.title %>
      </h2>
      <h6>
        <%= #{hit.score} %>
      </h6>
      <p>
        <%= truncate(post.body, :length => 100) %>
      </p>
    </div>
  <% end %>
</div>
<div class="pagination">
  <%= will_paginate(@search.results) %>
</div>

And there you have it — awesome fulltext search in your Rails app. Now you’re up and running, but there’s a lot more to learn — be sure to check out all the sections of the wiki to find out about all the powerful things Solr and Sunspot can do.

Common Initial Troubleshooting.

If you see: Errno::ECONNREFUSED (Connection refused - connect(2)) Then perhaps:

You have not started the solr server:
$ rake sunspot:solr:start

An error occurred in starting the solr server (such as not having the Java Runtime Environment installed). do
$ rake sunspot:solr:run
to run the server in the foreground and check for errors.

If you come across this error in testing but not development, then perhaps you have not invoked the task with the correct environment:
$ RAILS_ENV=test rake sunspot:solr:run