Railsでテーブルに関係ないmodelを作って検索処理を作ってみる(elasticsearchを使って)

今回検索用DBは考えた末にelasticsearchを使う事にしました。会社でも使われだしていて、何よりもHerokuでelasticsearchのAddOnが複数あったからです。mroongaをやるには結構大変そうだったので、これは別の機会に・・・。

で使うライブラリですが、昔やった時にあったtireは非推奨になったのでelasticsearch-persistenceを使う事にしました。

# elasticsearch対応
gem 'elasticsearch-persistence'

これをbundle insallで入れたら、まずはelasticsearchへの接続周りをやります。
色々やり方はあるようなのですが、今回使ったのは「elasticsearch-persistence」。

require 'elasticsearch/persistence'

module Search
  class Connection
    def self.connect
      @repository = Elasticsearch::Persistence::Repository.new do
        # Configure the Elasticsearch client
        client Elasticsearch::Client.new url: ENV['BONSAI_URL'], log: true, reload_connections: true

        # Set a custom index name
        index :test_app

        # Set a custom document type
        type :movie


        # Configure the settings and mappings for the Elasticsearch index
        settings number_of_shards: 1 do
          mapping do
            indexes :text, analyzer: 'kuromoji'
          end
        end
      end
      @repository
    end
  end
end

このelasticsearch-persistenceでは接続周りはElasticsearch::Clientクラスを使っているので、このクラス内で接続先などを環境変数で指定出来るように変更しました。またindexの値やdocumentのtypeの指定もしています。

で、次にelasticsearchにデータを入れるところですが、以下のように書けます。

class Movie < ActiveRecord::Base
  after_save :save_search_data

  def save_search_data
    # client = Search::Movie.new
    # client.index(self, index_value: 'koremita_app') unless Rails.env.test?
    Search::Connection.connect.save self unless Rails.env.test?
  end

  def to_hash
    { id: id, title: title, description: description, user_id: user_id }
  end
end

ここではActiveRecordのafter_saveコールバックメソッドを使ってデータが登録されたタイミングでelasticsearchに登録するように書いています。
to_hashメソッドでelasticsearchに入れるときにデータの形式を指定します。このメソッドがないとエラーになります。

次は検索する部分ですが、以下のように書きます。

      repository = Search::Connection.connect
      @results = repository.search(query: { match: { title: params[:search_movie][:title] } })

これで@resultsに検索結果がセットされるので、view側で表示するだけです。
今日はここまでです。もっと調べて情報が溜ったら、この件についてまた書きます。