Help us understand the problem. What is going on with this article?

railsから全文検索エンジンelasticsearchを利用する

More than 5 years have passed since last update.

ElasticSearchとは

ElasticSearchはSolrと同じApache Lucene上で稼働するオープンソースの全文検索システムです。

ElasticSearchの特徴としては、REST APIが整備されていて、JSONですべてやり取りできるところです。

準備

ElasticSearchはJavaで動作するので事前にJavaのインストールが必要です。

ElasticSearchのインストールはMacならbrewがあるので簡単です。

$ brew install elasticsearch

WindowsでもZipをダウンロードして、batファイル叩くだけだったので楽です。

ElasticSearchには様々なプラグイン
が用意されており、その中に日本語対応の物も用意されています。

kuromojiを用いたelasticsearch-analysis-kuromojiを使います。

プラグインのインストールも簡単で用意されているpluginコマンドにgitの短縮アドレスを渡して叩くだけです。

$ plugin --install elasticsearch/elasticsearch-analysis-kuromoji/1.5.0

これでkuromojiをプラグインとして利用可能となりました。

日本語対応させる際に、後述するrailsのmodelでフィールド毎にAnalyzerとしてkuromojiを指定することも出来ますし、デフォルトのAnalyzerとして利用したければ設定ファイル(macなら/usr/local/opt/elasticsearch/config/elasticsearch.yml)に以下を追記して指定することも可能です。

index.analysis.analyzer.default.type: custom
index.analysis.analyzer.default.tokenizer: kuromoji_tokenizer

ブラウザからElasticSearchの状態を確認できるプラグインも複数用意されています。

今回は基本的なelasticsearch-headを導入してみます。

$ plugin --install mobz/elasticsearch-head

elasticsearch-headプラグイン導入後はhttp://localhost:9200/_plugin/head/にアクセスすることでブラウザから様々な確認が出来るようになります。

サンプルRailsアプリ

ElasticSearchを扱うためのサンプルアプリを作成します。

bundle initしてGemfilerails追加してbundle exec rails newします。

全文検索を試したいので、ニュースの記事を扱うようにしてみます。

記事のモデル名をarticleにして、タイトルと本文を持つようにしてみました。

$ bundle exec rake db:create                                                                                                               
$ bundle exec rails g scaffold article title:string body:text                                                                              
$ bundle exec rake db:migrate

連携

RailsとElasticSearchとの連携にはtireを使います。

Gemfilegem 'tire'を追加してbundle intallします。

次にmodelにElasticSearchとの連携を記述します。

app/models/article.rb

class Article < ActiveRecord::Base
  include Tire::Model::Search
  include Tire::Model::Callbacks

  mapping do
    indexes :title, analyzer: :kuromoji
    indexes :body, analyzer: :kuromoji
  end

  def self.search(params)
    tire.search(load: true) do
      query {
        string "body:#{params[:search]} title:#{params[:search]}"
      } if params[:search].present?
    end
  end
end

ControllerはArticle.allの呼び出しをElasticSearchからの検索に変更します。

app/controllers/articles_controller.rb#index

def index
    @articles = Article.search(params)
    # @articles = Article.all
end

Viewに検索のボックスを追加します。

app/views/articles/index.html.erb

<%= form_tag articles_path, :method => :get do %>
  <%= text_field_tag :search, params[:search] %>
  <%= submit_tag "Search", :name => nil %>
<% end %>
<%= link_to 'clear', articles_path %>

これで
http://localhost:3000/articlesにアクセスして
適当にニュース記事のデータを突っ込んで、
検索窓にワードを打ち込めば検索可能になっています。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした