RailsアプリでElasticsearchを扱うならchewyがおすすめ
Twitterでツイートしたり、表参道.rbの懇親会では紹介していたけど、ブログに書いていなかったので今更ながらまとめておきます。
Chewyの利点
READMEを一通り読んでもらうと 最高に便利なのが分かる とは思うのですが、それだと身も蓋もないので個人的に良いと思ってる機能を3つだけ紹介します。
- 複数のストラテジ
- ゼロダウンタイムのインデックス更新に対応したrakeタスク
- Named scopes
1. 複数のストラテジ
Chewyにはデフォルトで複数のストラテジが用意されてあります。
:atomic
: 一括でインデックスを登録する:urgent
: 1つずつインデックスを登録する:bypass
: インデックスに登録しない:active_job
: 非同期処理でインデックスに登録する(:sidekiq
などを直接使う事も可能)- ...など
これらのストラテジは最初から良い感じに設定してあります。
rails console --sandbox
だとElasticsearchに登録しない- マイグレーション処理ではElasticsearchに登録しない
- コントローラーだと
:atomic
になって、リクエスト単位で一括登録される - 参考: https://github.com/toptal/chewy/blob/v5.0.0/lib/chewy/railtie.rb
また、一時的にストラテジを切り替えることもできます。
Chewy.strategy(:bypass) do City.popular.map(&:do_some_update_action!) end
2. ゼロダウンタイムのインデックス更新に対応したrakeタスク
READMEから説明を引用して紹介します。
Performs zero-downtime reindexing as described here. So the rake task creates a new index with unique suffix and then simply aliases it to the common index name. The previous index is deleted afterwards (see Chewy::Index.reset! for more details).
要は、「新しいインデックスを作って、エイリアスで切り替えるとゼロダウンタイムで更新できる」というもので、これに対応したrakeタスクが標準で用意されています。 しかもrakeタスクは最初から並列実行に対応しています。
あと、フィールドに updated_at
が含まれていれば chewy:sync
のタスクでDBとElasticsearchの同期を簡単に行うことができます。
基本的には使わないのですが、何かしらの理由でデータ不整合が起きた時に簡単に修正できて便利です。
参考: https://github.com/toptal/chewy/blob/v5.0.0/lib/chewy/type/mapping.rb#L192
3. Named scopes
ChewyではActiveRecordのようにScopeを定義することができます。
class UsersIndex < Chewy::Index def self.by_name(name) query(match: { name: name }) end end UsersIndex.limit(10).by_name('Martin') #=> <UsersIndex::Query {..., :body=>{:size=>10, :query=>{:match=>{:name=>"Martin"}}}}>
これは検索機能のように複数の条件を組み合わせるときに便利です。
class UsersIndex < Chewy::Index def self.by_name(name) # 検索フォームに未入力の場合を考慮 return all if name.blank? query(match: { name: name }) end def self.in_followers(user) query(match: { follower_ids: user.follower_ids }) end end UsersIndex.by_name(params.dig(:q, :name)).in_followers(current_user) #=> <UsersIndex::Query {..., :body=>{:query=>{:bool=>{:must=>[{:match=>{:name=>"Martin"}}, {:match=>{:follower_ids=>[1, 2]}}]}}}}>
まとめ
RailsでElasticsearchを使う場合、elasticsearch-railsを選ぶ人が多いとは思いますが、是非Chewyも検討してみてください。
私は去年の11月にchewyを見つけたけど、READMEを読んでelasticsearch-railsからchewyへの乗り換えを決めました。
最近、chewyのgemを知ったけど、これ8月に知っておきたかった。elasticsearch-railsはこれからの戦いについてこれないので、外した。
— 神速 (@sinsoku_listy) 2018年11月13日