Tinia

A Rails interface for Amazon CloudSearch

Tinia allows you to easily index and search data using Amazon’s hosted Solr service, CloudSearch. Its basic workflow is that after_save we send data to CloudSearch and after_destroy we remove that data.

Installing tinia

In Rails 3

# Gemfile
gem "tinia"

In Rails 2

# config/environment.rb
config.gem "tinia"

# config/initializers/nimbus.rb
Tinia.activate_active_record!

Activating the Model

In order to activate a given model, you call the indexed_with_tinia class method. You must also supply a tinia_domain. The tinia_domain is inheritable, so subclasses will use the same tinia_domain as their parent.

class User < ActiveRecord::Base
  indexed_with_cloud_search do |config|
    config.cloud_search_domain = "users-xkdkdksl485d8d0d"
  end
end

Indexing data

In order to define the fields that you want indexed, you must define a cloud_search_data method, which returns a hash of indexed data. You can call any necessary methods to generate this data.

class User < ActiveRecord::Base

  indexed_with_cloud_search do |config|
    config.cloud_search_domain = "users-xkdkdksl485d8d0d"
  end

  def cloud_search_data
    {
      "name" => self.name,
      "age" => self.age,
      "fathers_name" => self.father.name,
      "mothers_name" => self.mother.name
    }
  end

end

Each time a record is saved, the index for that record will be updated. When the record is destroyed, it is removed from the index.

Indexing a collection

When installing tinia, you will need to build your initial index. The index is built by finding each record and adding it to a batched uploader. This is done for efficiency (but large collections will still be kind of slow).

The re-indexer uses find_each and takes the same arguments as that method.

# Eager load associated data
Client.cloud_search_reindex(:include => [:mother, :father])

Searching

Searching is implemented as a named_scope with extensions to hold meta data about the result set

res = Client.cloud_search("Dan") # => will search our collection for records with a type of Client that matches the query "Dan"

Client.cloud_search("Dan").recent # => applies the 'recent' scope to our conditions generated by a result from CloudSearch

Pagination

CloudSearch/Solr offers built-in pagination, which Tinia provides access to. For example

# default options
res = User.cloud_search("Dan")
res.current_page # => 1
res.per_page # => 20
res.offset # => 0
res.total_pages # => 5
res.total_entries # => 89

# with additional options
res = User.cloud_search("Dan", :page => 2, :per_page => 30)
res.current_page # => 2
res.per_page # => 30
res.offset # => 30
res.total_pages # => 3
res.total_entries # => 89

WillPaginate

Tinia offers drop-in integration with will_paginate. Results of any Tinia search will work with the will_paginate view helpers

# app/controllers/users_controller.rb
class UsersController < ApplicationController
  # GET /users
  def list
    @users = User.cloud_search(params[:q])
  end
end

# app/views/users/list.html
= will_paginate(@users)

Contributing to Tinia

  • Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet.

  • Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it.

  • Fork the project.

  • Start a feature/bugfix branch.

  • Commit and push until you are happy with your contribution.

  • Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.

  • Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.

Copyright © 2012 Dan Langevin and Lifebooker. See LICENSE.txt for further details.