FullText search with Sunspot

Recently I had to implement the full text search functionality in my project.Had couple of options in my hand, as there are some good gems available in the rails community.

listed some of them below

1. sunspot + solr (https://github.com/outoftime/sunspot)
2. acts_as_indexed (https://github.com/dougal/acts_as_indexed)
3. thinking-sphinx (https://github.com/freelancing-god/thinking-sphinx)
4. tire + elasticsearch (https://github.com/karmi/tire)

All of the gems listed above are widely used and it won’t be good to make any comparisons on there usage and performance. Here
i show you how i integrated Sunspot in my rails project.

Sunspot is a Ruby library for expressive, powerful interaction with the Solr search engine. So when integrating it with the rails project the only thing we need to require is the sunspot_rails gem as it also comes with the solr libraries and we don’t have to explicitly install it. The key strengths of sunspot would be the extensibility and to scale up to larger data better.

1. Installing sunspot_rails gem.

Include the sunspot_rails gem in your gem file.

gem 'sunspot_rails'

and run bundle install .

2. Generating the sunspot.yml file.

rails generate sunspot_rails:install

3. Start the Solr server.

rake sunspot:solr:start

to stop the server

rake sunspot:solr:stop

4. Add the searchable block to the model we want to search on.

inside the block we have to define the attributes to search by.

so inside the model we would have something like this

class Item < ActiveRecord::Base
  belongs_to :category
  searchable do
    text :name
    text :description, :stored => true
    integer :category_id
    float :price
  end
end

5. Reindex the existing records in the database.

rake sunspot:reindex

this command would reindex the existing records in the database.We don’t have to worry about the new records that are been added as Sunspot would automatically indexed them for us.

6. Setting the search variable inside the controller method.

def index
  search = Item.search do
    fulltext params[:search_query]
    paginate :page => params[:page], :per_page => 5
  end
  @items = search.results
end

here inside the search block we can use different methods to perform the search.for e.g. the fulltext method with the params parameter.

here search.results would return the array of all the items.

7. Inside the index.html.erb

:get do %>

8. Implementing the Faceting search

this is one of the most powerful feature of Solr that helps to filter the search criteria according to certain conditions.for example if we want to list all the items according to the categories they fall into.

for implementing the faceted search we need to make some changes in our index method and view, which will make our method and view to look something like this

inside controller

def index
  search = Item.search do
    fulltext params[:search_query]
    paginate :page => params[:page], :per_page => 5
    facet(:category_id)
    with(:category_id, params[:category]) if params[:category].present?
  end
  @items = search.results
  @search=[]
  search.facet(:category_id).rows.each do |facet|
    @search << Category.fetch_category_name(facet.value)
  end
end

inside view

Categories

  • search.id %>

(defining fetch_category_name method inside the category model)

class Category < ActiveRecord::Base
  has_many :items
  def self.fetch_category_name(value)
    find_by_id(value)
  end
end

9. Starting the Solr server in Production.

If you are in production its recommended that you don’t use the rake task to start the Solr server, instead you can fire this command which will start a daemon process.

sunspot-solr start -- -p 8983 -d data/solr/myapp

now if you check your sunspot.yml file that you generated inside /config directory.you would find this 8983 port defined and the other configuration settings.

There are lot more options that we can add to the search functionality with Sunspot Solr and i would recommend to take a look at the Sunspot documentation.

Leave a Reply

Your email address will not be published. Required fields are marked *

eighteen + 19 =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>