LoginSignup
12
10

More than 5 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

12
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
10