Posted at

sunspot使ってみた

More than 3 years have passed since last update.

検索エンジンのsunspotを使ってみた。


モデル定義

class Post < ActiveRecord::Base

searchable do
text :title, :body

boolean :featured
integer :blog_id
integer :author_id
integer :category_ids, :multiple => true
double :average_rating
time :published_at
time :expired_at
end
end

こんな感じで定義する

relationの定義を行いたいときは

  text :comments do

comments.map { |comment| comment.body }
end

string :comment_title, multiple: true do
comments.map { |comment| comment.title }
end

string :author_name do
author.name
end

こんな感じで。text型はmultipleオプションを付けられない。

アソシエーション先がnilの場合があるのであれば、tryとか使ってうまく回避。


検索してみる

search = Post.solr_search do |query|

fulltext('hoge', fields: :title)
end

単純にtext型の複合(AND)条件であれば、

search = Post.solr_search do |query|

fulltext('hoge', fields: :title)
fulltext('fuga', fileds: :body)
end

これでOK

OR条件にするのであれば

search = Post.solr_search do |query|

query.any do
fulltext('hoge', fields: :title)
fulltext('fuga', fileds: :body)
end
end

fulltext以外の項目ならば、any doany_of doに変わります・・・。

search = Post.solr_search do |query|

query.any_of do
with(:blog_id, 111)
with(:author_id, 222)
end
end

これらを組み合わせて使うと・・・

search = Post.solr_search do |query|

query.any do
fulltext('hoge', fields: :title)
fulltext('fuga', fileds: :body)
end
query.with(:blog_id, 111)
query.with(:author_id, 222)
end

ページネートにも対応しているので、

項目を追加してやると良いです。

ちなみにデフォルトでページネートされ、1ページに全件を指定はできないそうなので、

その場合はper_pageに最大値の1000万を指定するか、Post.countとか渡して対応しましょう

  paginate(page:1, per_page:50)

あとは結果を取得するだけ(results or hits)

search.results

管理画面なども用意されているので、ブラウザでアクセスして

クエリやindexの確認ができます。

なかなか使う機会は限られるかもしれませんが、参考まで。

sunspot

https://github.com/sunspot/sunspot