10
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SpeeeAdvent Calendar 2015

Day 8

elasticsearch-rails/erasticsearch-persistenceについて

Posted at

Speeee Advent Calendar 8日目です。

elasticsearch

ここ約3ヶ月ほど全く触ったことのないElasticsearchを使うプロジェクトにアサインされ、よくわからんことだらけだった中でネット上に日本語であまり見当たらなかったような気がしたelasticsearch-persistenceについて軽くまとめられればなーと思っております。

使用してる環境

elasticsearch(1.7.2)
elasticsearch-persistence (0.1.8)
rails(4.2.3)
ruby(2.2.3)

なぜpersistenceを使ったのか

アプリケーションにテーブルの存在するモデル(ActiveRecordを継承したモデル)にelasticsearchによる検索を適応する場合には、Elasticsearch::Modelを利用することで、そのモデルにelasticsearchの機能が付与することができます。
ただ、今回私が携わってきたプロダクトではテーブルが存在しないモデル(ActiveRecordを継承しないモデル)でelasticsearchを使った検索をしたかったためpersistenceを使うことにしました。

Elasticsearch::Persistenceの2つの実装方法

persistenceには

Repositoryタイプ

この場合はrepositoryがelasticsearchへの検索、参照、保存、削除などを担っており、repositoryへsaveメソッドの引数として値の入ったモデルを入れることにより、保存してくれたりします。
repositoryパターンを提供したものであるようです。

ActiveRecordタイプ

こちらは文字通りActiveRecordのモデルと同じ感覚でElasticsearchの検索などを使えるようにするものです。
今回はこちらを採用しました。
理由はいつものrailsっぽく使えるから、という理由のみです。

ModelとRepositoryの関係

ActiveRecordタイプで実装するものでも、内部的にはRepositoryを使っていて、その利用が隠蔽されているだけに過ぎないので、例えばElasticsearch::Persistence::ModelをincludeしたHogeモデルがあるとすると

Hoge.gateway

にElasticsearch::Persistence::Repositoryが格納されています。

Elasticsearch::Persistence::Modelの使い方

include Elasticsearch::Persistence::Model

ってモデルに書けばOK
Elasticsearch::Persistence::Model自体はvirtusとActiveModelが入っているのでこれ入れるだけで基本的なモデルがかけます。

hoge.rb
class Hoge
  include Elasticsearch::Persistence::Model

  attribute :fuga,  Integer
  validates :fuga,  presence: true
end

こいつに.saveとかやれば保存してくれたり、.search(#{query})とかやれば検索してくれて検索結果を取得できます。
検索結果として戻ってくるのはElasticsearch::Persistence::Repository::Response::Resultsですが、eachなどで展開すると直接呼び出したモデルに格納された状態で操作できます。
直接呼び出したモデルなので、例えば親クラスでのみincludeしておいて、その小クラスで検索した場合には親クラスに格納された結果になるので少し注意が必要です。
また、aggregationを利用した場合にはこの限りではないので、直接値を掘り出して、モデルに格納するなどの操作が必要です。

indexとdocumentの指定方法

index_name 'hoge'
document_type 'fuga'

と書けばOK
書かないとクラス名から推測されて勝手に作られます。

hoge.rb
module Elasticsearch
  class Hoge
    include Elasticsearch::Persistence::Model
    
    index_name 'hoge'        # add
    document_type 'fuga'     # add

    attribute :fuga,  Integer
    validates :fuga,  presence: true
  end
end

indexの強制更新

よくelasticsearchを実際に使ったrspecなどのテストでelasticsearchにデータ入れた後すぐ反映したい場合、

{Elasticsearch::Model}.__elasticsearch__.create_index!
{Elasticsearch::Model}.__elasticsearch__.flush_index!

と書きますが、persistenceの場合は

{Elasticsearch::Persistence::Model}.gateway.create_index!
{Elasticsearch::Persistence::Model}.gateway.flush_index!

となります。
つまり、persistenceの場合には__elasticsearch__に対応するのがgatewayになるので、Elasticsearch::Modelを使っている記事の__elasticsearch__gatewayに読み替えれば結構いけること多いです。

hostを環境毎に変更する

めっちゃ普通

config/initializer/elasticsearch.rb
Elasticsearch::Persistence.client = Elasticsearch::Client.new(host: ENV['ELASTICSEARCH_HOST'], logs: Rails.env.development?, trace: Rails.env.development?)

これはほとんどElasticsearch::Modelの記事を参考にさせていただきました。
参考: RSpecでElasticsearchを使ったテストを書く

おわりに

persistenceを使った場合の本当に基本的なところと、Elasticsearch::Modelとちょっと違うところをまとめました。
当時は右も左も分からない状態で疑う箇所が多かったので、直接persistenceを使った記事少なくて困ったなーと思っていましたが、今になってみると結局要点を抑えればElasticsearch::Modelを利用した記事を参考にすれば良いということです。

10
14
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
10
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?