Searching multiple models w/ Thinking Sphinx

July 28th
by dylan

Thinking Sphinx is a really sweet Ruby library that hooks ActiveRecord to Sphinx and hooks up to will_paginate out of the box.

Sphinx is a very fast search engine that indexes data and provides flexible ways of searching it. Thinking Sphinx allows you to link up your models into Sphinx simply and painlessly – because let’s face it, searching across multiple fields using SQL is a pain in the neck.

TS is easy to implement and reliable (haven’t seen any corrputed indexes yet) – we are using it on the new Artlog (and in combination w/ Geokit geographic for geographic + text searches).

Ryan Bates posted a good intro tutorial this morning over at railscasts.

Here’s a quick tip for folks looking to search across multiple models at once.

You’d traditionally build your actions this way (search_controller.rb):

def notes
  @notes = Note.search params[:search], :per_page => 10, :page => params[:page]
end

def users
  @users = User.search params[:search], :per_page => 10, :page => params[:page]
end

But to search across multiple models, you can interact with ThinkingSearch::Search directly and set the action up thusly:

def index
  @results = ThinkingSphinx::Search.search params[:search], :per_page => 10, :page => params[:page]
end

And the view could look something like this:

<%- @results.each do |result| -%>
  <% if result.class == Note %>
    <%= render :partial => 'notes/note', :locals => {:note => result } %>
  <% elsif result.class == User %>
    <%= render :partial => 'users/user', :locals => {:user => user } %>
  <% end %>
<%- end -%>
<%= will_paginate @results %>

I am rendering the user and note results in partials – you don’t have to do it precisely this way, of course. It’s just to get you started.

Top / © 2007-2008 I Am Still Alive. All rights reserved. Information