検索機能を実装するときによく使われているElasticsearchをRailsで使うためのサンプルアプリケーションの作成の手順を作りました。入門レベルです!
🐮 Elasticsearchの導入
拙著『Elasticsearch 2.1 + Kibana 4.1 + Marvel のMacへのセットアップ 』を良ければご参考ください。
🍄 Railsサンプルアプリケーション
Railsのサンプルアプリケーションを作成します。今回は Article
(記事) のモデルをもつことにします。
# Railsアプリの作成 rails new elasticsearch_sample --skip-bundle # フォルダを移動 cd elasticsearch_sample # DBの作成 rake db:create # article テーブルの定義を作成 bundle exec rails g scaffold article title:string body:text # article テーブルを作成 bundle exec rake db:migrate
GemfileにElasticsearch用のgemを追加します。
gem 'elasticsearch-model' , git: 'git://github.com/elasticsearch/elasticsearch-rails.git' gem 'elasticsearch-rails' , git: 'git://github.com/elasticsearch/elasticsearch-rails.git'
追加したらターミナルで次のコマンドを実行してgemをインストールします。
bundle install --jobs=4 --path=vendor/bundle
🐞 ModelにElasticsearchを使うための設定 次にArticle
モデルにElasticsearchを使うための設定をします。
class Article < ActiveRecord::Base include ArticleSearchable end
今回はconcernにElasticsearchに関する処理を切り出します。
module ArticleSearchable extend ActiveSupport::Concern included do include Elasticsearch::Model INDEX_FIELDS = %w(title body) .freeze index_name "es_sample_article_#{Rails.env} " settings do mappings dynamic: 'false' do indexes :title , analyzer: 'kuromoji' , type: 'string' indexes :body , analyzer: 'kuromoji' , type: 'string' end end def as_indexed_json (option = {}) self .as_json.select { |k, _| INDEX_FIELDS.include ?(k) } end end module ClassMethods def create_index! client = __elasticsearch__ .client client.indices.delete index: self .index_name rescue nil client.indices.create(index: self .index_name, body: { settings: self .settings.to_hash, mappings: self .mappings.to_hash }) end end end
インデックス名には環境情報をつけておきます。
理由はlocalでのテストをしやすくするためです。
🐡 index作成のRakeタスクを作成 続いてindexを作成するRakeタスクを作ります。
まずはRakeタスクを作成するために、次のコマンドをターミナルで実行します。
rails g task elasticsearch
作成されたRakeタスクを以下のように変更します。
namespace :elasticsearch do desc 'Elasticsearch のindex作成' task :create_index => :environment do Article.create_index! end desc 'Article を Elasticsearch に登録' task :import_article => :environment do Article.import end end
ではインデックスを作成します。
bundle exec rake elasticsearch:create_index
http://localhost:9200/_plugin/head/
にアクセスして「es_sample_article_development => info => Metadata」 の中身が以下のようになっていたら成功です!
ちなみに、curlコマンドでもマッピングを確認できます。 ターミナルで次のコマンドを実行してみてください。
curl -XGET 'localhost:9200/es_sample_article_development/_mapping/article?pretty=true' { "es_sample_article_development" : { "mappings" : { "article" : { "dynamic" : "false", "properties" : { "body" : { "type" : "string", "analyzer" : "kuromoji" }, "title" : { "type" : "string", "analyzer" : "kuromoji" } } } } } }
🏀 サンプルデータの作成 サンプルデータを作成します。
ActiveRecord::Base.transaction do Article.delete_all 10 .times do |idx| Article.create!( title: "タイトル #{idx} " , body: "本文 #{idx} " ) end end
Elasticsearchにデータを登録します。
# サンプルデータの生成 bundle exec rake db:seed # Elasticsearchへの登録 bundle exec rake elasticsearch:import_article
http://localhost:9200/_plugin/head/
から「Structured Query」を選択していろいろいじるとデータが格納されていることが分かると思います!
ちなみに、rails console
からでもいろいろ試せるのでぜひいろいろ遊んでみてください!
Article.search('9' ).results.count Article.search('9' ).results.first =#<:mash _id="10" _index="es_sample_article_development" _score="1.1972358" _source="#<Hashie::Mash" body="本文 9" created_at="2016-01-03T11:02:46.578Z" id="10" title="タイトル 9" updated_at="2016-01-03T11:02:46.578Z"> _type="article">> Article.search(query: {term: {title: "5" } }).records.first
🍮 とりあえず一覧の検索を実装 articles_controller
の index
を次のように変更。
class ArticlesController < ApplicationController def index @articles =if params[:search ] Article.search(params[:search ]).records else Article.all end end end
viewも以下を追加。
<%= form_tag articles_path, :method%=> => :get do %> <%= text_field_tag :search%=> , params[:search ] %> <%= submit_tag 'Search'%=> , :name => nil %><% end%> %>
http://localhost:3000/articles
にアクセスすれば検索できると思います!
👽 参考リンク
🖥 VULTRおすすめ
「VULTR 」はVPSサーバのサービスです。日本にリージョンがあり、最安は512MBで2.5ドル/月($0.004/時間)で借りることができます。4GBメモリでも月20ドルです。
最近はVULTR のヘビーユーザーになので、「ここ 」から会員登録してもらえるとサービス開発が捗ります!