Indexing your Models

Everything to set up the indexes for your models goes in the define_index method, within your model. Don’t forget to place this block below your associations, otherwise any references to them for fields and attributes will not work.

class Article < ActiveRecord::Base
  # ...
  
  define_index do
    indexes subject, :sortable => true
    indexes content
    indexes author(:name), :as => :author, :sortable => true
    
    has author_id, created_at, updated_at
  end
  
  # ...
end

Fields

The indexes method adds one (or many) fields, by referencing the model’s column names.

indexes content

Keep in mind that if you’re referencing a column that shares its name with a core Ruby method (such as id, name or type), then you’ll need to specify it using a symbol.

indexes :name

You don’t need to keep the same names as the database, though. Use the :as option to signify an alias.

indexes content, :as => :post

You can also flag fields as being sortable.

indexes subject, :sortable => true

Use the :facet option to signify a facet.

indexes authors.name, :as => :author, :facet => true

If there are associations in your model, you can drill down through them to access other columns. Explicit aliases are required when doing this.

indexes author(:name), :as => :author
indexes author.location, :as => :author_location

There may be times when a normal column value isn’t exactly what you’re after, so you can also define your indexes as raw SQL:

indexes "LOWER(first_name)", :as => :first_name, :sortable => true

Again, in this situation, an explicit alias is required.

Attributes

The has method adds one (or many) attributes, and just like the indexes method, it requires references to the model’s column names.

has author_id

The syntax is very similar to setting up fields. You can set aliases, and drill down into associations. You don’t ever need to label an attribute as :sortable though – in Sphinx, all attributes can be used for sorting.

has tags(:id), :as => :tag_ids

Conditions and Groupings

Because the index is translated to SQL, you may want to add some custom conditions or groupings manually – and for that, you’ll want the where and group_by methods:

define_index do
  # ...
  
  where "status = 'active'"
  
  group_by "user_id"
end

Processing your Index

Once you’ve got your index set up just how you like it, you can run the rake task to get Sphinx to process the data.

rake thinking_sphinx:index

As each model is processed, you will see a message much like the one below. It is just a warning, not an error. Everything will work fine.

distributed index 'article' can not be directly indexed; skipping.

However, if you have made structural changes to your index (which is anything except adding new data into the database tables), you’ll need to stop Sphinx, re-index, and then re-start Sphinx – which can be done through a single rake call.

rake thinking_sphinx:rebuild