sunspot_rails
sunspot_rails/README.rdoc at master from outoftime/sunspot - GitHubの意訳。
Sunspot::Rails は Sunspot の Solr 検索を Rails に統合するためのプラグイン。下記のような機能を提供する。
- config/sunspot.yml で sunspot の設定が出来る
- ActiveRecord を拡張してインデックスの作成/設定と検索とを楽にする
- ActiveRecordのオブジェクトが保存されたときや削除されたときに自動でインデックスも作成/削除される(機能をオフにすることも出来る)
- 自動で各リクエストの最後に Solr の変更をコミットする(機能をオフにすることも出来る)
- 孤立したドキュメントを探して直してインデックスを再構築するメソッドを提供
- Solr インスタンスを sunspot.yml の設定を利用しつつ起動したり中止したり出来る
Rails の 2.3 と 3.0 でテストされている。
インストール
Gemfile
gem 'sunspot_rails'
Sunspot::Rails を使う
Solr スキーマを修正したい場合、RAILS_ROOT/solr/conf を作って、Solr gem の solr/solr/conf ディレクトリの中身をコピーする。ファイルが正しい場所に存在する場合、Sunspot::Rails はそれを検知して Solr にその設定を使うように指示する。schema.xml を修正したときには注意すべき。Sunspot relies on the field naming scheme in the packaged schema file.
Solr インスタンスを開始するには下記のようにする。
rake sunspot:solr:start
Sunspot と一緒にパッケージされている Solr インスタンスは開発用であり、production では推奨されない。詳しくはSunspot のドキュメント読んで。
検索とインデックス作成用の設定
検索とインデックス作成用の設定は下記のようにする。
class Post < ActiveRecord::Base searchable do text :title, :body integer :blog_id time :updated_at string :sort_title do title.downcase.sub(/^(an?|the) /, '') end end end
ブロック中に何が出来るのかは Sunspot.setup のドキュメントを参照のこと。
インデックスの更新
保存したときに自動でインデックスの更新、削除したときに自動でインデックスの削除をするのを下記のようにすることでやめさせることが出来る。
class Post < ActiveRecord::Base searchable :auto_index => false, :auto_remove => false do # setup... end end
auto_remove は推奨されない。インデックスを削除せずにオブジェクトを削除すると、孤立したドキュメントがインデックスに残ってしまう。これはよくない。auto_indexをオフにするのは、手動でインデックスを更新すればいいので問題ない。
もしインデックス変更のフックをオフにした場合、下記のように直接インデックスを変更できる
post = Post.create
post.index
post.remove_from_index
committing
Solr 内でデータが変更されたとき、それは最初にメモリに入れられる。そのときに走っている検索用のインスタンスは変更したデータを使えない。Solr にコミットすると、変更をディスクに書き込んで、新しい検索用のインスタンスを作る。この操作はかなりコストが高い。ドキュメントが作成されるか削除されるかしたときに毎回コミットするようなことをせずに、Sunspot::Rails は各リクエストの最後にコミットする。すぐにコミットしたい場合は下記のように!をつける。
post = Post.create post.index! # this is the same as... post.index Sunspot.commit
コントローラのリクエストの外のコンテキストのテストを書くときには、これらの二つのどちらかやり方を使う。
検索
こんな風にする
Post.search do with :blog_id, 1 with(:updated_at).greater_than(Time.now - 2.weeks) order :sort_title, :asc paginate :page => 1, :per_page => 15 end
ブロック中で使える全てのオプションを知りたければ Sunspot.serach のドキュメントを見るべし。
ID の検索
検索したときに、モデルのIDだけ取得したいときがあるかもしれない。search_ids メソッドを使うと、search と同じ検索の仕方で、戻り値はIDの配列。
複数テーブルの検索
Sunspot は検索の対象が一つなのか二つ以上なのか知らない。Sunspot::Rails はこのへんサポートしてないので Sunspotのインタフェースを使う。
Sunspot.search(Post, Comment) do with :blog_id, 1 order :created_at, :asc end
詳しくは Sunspot のドキュメントを参照のこと。
検索機能を mixin で追加する
SunSpot は一箇所に設定を置く必要がない。Sunspot.setup メソッドは二回以上呼び出すことが出来る。これはmixinで検索機能を加えるときに使える。例えば追加の検索フィールドを、Ratable モジュールを mixin したクラスに加えたい場合は下記のようにする
module Ratable def self.included(base) if base.searchable? base.searchable do float :average_rating do ratings.average(:value) end end end end end
base.serachable? は検索の設定がすでにされており、追加で設定可能かどうかを返す。上記のコードを使うには、 mixin する前に既に searchable を設定している必要がある。
ユーティリティメソッド
モデルに紐付いたインデックスを再構築するには下記のようにすることができる
Post.reindex
もし何らかの理由でモデルがDBから削除され、インデックスからは削除されなかった場合、それらは孤立する。インデックスにあるけどDBにないモデルのIDを得るために、 index_orphans メソッドが用意されている。インデックスからそれらを削除するために、 clean_index_orphans メソッドが用意されている。いずれのメソッドも使う必要があるような状況にするべきではない。
Rspec で Solr を使ったテストをする
ActiveRecord のモデルを扱う際に、sunspot と Solr の統合をオフにするにはまず require 'sunspot/rails/spec_helper' とする。それから下記のように disconnect_sunspot メソッドを使う
require 'sunspot/rails/spec_helper' describe Post do disconnect_sunspot it 'should have some behavior' # ... end end
上記の examples はすべての Sunspot の呼び出しが stub out される。Sunspot#serach メソッドが stub 化された、結果が何も入っていない search オブジェクトを返すようになる。
もっとくわしく
Sunspot のドキュメントを読むべき。Sunspot::Rails は Sunspot のラッパなので、Sunspot::Rails の機能はすべて Sunspot に実装されている。
Sunspot 1.2.rc3 - Solr-powered search for Ruby objects - API Documentation