A Few SunSpot Tips

I started playing with SunSpot yesterday with the intent of using it as my full-text search provider in a Rails application. The few how-tos I found show the beautiful DSL it provides, but unfortunately not much more. Below are a few gotchas I ran into while getting it to work on my setup.

1. Sunspot includes a development version of Solr

There's no need to download an official Solr release from Apache for development work. Just install sunspot and you get Solr for free, complete with some nice Rake tasks.

gem install sunspot

rake sunspot:solr:start --starts the solr server

rake sunspot:solr:stop --stops the solr server

2. Using Sunspot in Rails requires the sunspot_rails gem

This one was easy to solve, but still surprised me a bit. The sunspot gem only provides the base interaction with the Solr server. In order to get ActiveRecord integration, you need to add the sunspot_rails gem:

# config/environment.rb
config.gem 'sunspot', :lib => 'sunspot'
config.gem 'sunspot_rails', :lib => 'sunspot/rails'

$ rake gems:install

3. Text Analysis is setup in Solr, not in Sunspot

It seems there's not much written in the Sunspot documentation/groups about text analysis (such as word stemming, stop word filters, synonyms analysis, etc), and for good reason. These settings are defined in Solr's setup via the schema.xml file. More details on Solr's text analysis abilities can be found on Apache's website. If you're using the install you get with Sunspot, you can find this in RAILS_ROOT/solr/conf/schema.xml.

4. Sunspot executes its search DSL in a new scope

This one took me forever to figure out. By default, any details passed into Sunspot.search are not evaluated in the current context. This means that trying to search directly from the controller just doesn't work as I expected. There's no mention of this in sunspot_rails' documentation, but there's a brief snippet in sunspot's:

If the block passed to search takes an argument, that argument will present the DSL, and the block will be evaluated in the calling context. This will come in handy for building searches using instance data or methods

So, in order to search from the controller (or rather in the model, like you should), you'll need to pass an argument to the Sunspot.search block:

@search = Sunspot.search(Post) do |query|
query.keywords params[:query]
end
blog comments powered by Disqus