Rails - Tire と 全文検索エンジン Elasticsearch (2)
Rails - Tire と 全文検索エンジン Elasticsearch (1) の続きです
はじめに
今回の例は elasticsearch をバックグラウンドで動作させます。
bin/elasticsearch
で実行します。
Elasticsearch のインデックス
検索エンジンの要であるインデックスを操作します。
前回も例で示しましたが、Elasticsearchは RESTful なアプリケーションです。 クライアントは curl で行えます。ブラウザでもOKです。
REST はHTTPの以下の4種類のMETHOD(formタグで指定するアレです)から、 操作を行うものです。 Elasticsearch でのインデックスの使われ方はおおざっぱに次の通りです。
- GET - インデックスを取得する・検索する
- POST - インデックスデータを新規追加する
- POST - インデックスデータを更新する
- DELETE - インデックスデータを削除する
インデックスの作成
とあるブログ(架空)を例にします。POSTメソッドで新規作成になります。
$ curl -XPOST http://localhost:9200/blog/article -d '{
"title": "増し増しに沈没",
"tags" : ["Ruby","ラーメン二郎"],
"content": "ラーメン二郎にチャレンジしました\n増し増しに撃沈\n胃薬飲んでかえります",
"published_on": "2013-08-31T22:07:18+09:00"
}'
URL の パス名の部分が重要です。
戻り値は次の通り。 キーが _id のものがこのインデックスの固有のidになります。
{"ok":true,"_index":"blog","_type":"article","_id":"UZZ-CFdLTmCce1AnDJVzmg","_version":1}
PUT メソッドを使うとidを指定しての更新(新規作成)も可能です。
$ curl -XPUT http://localhost:9200/blog/article/1 -d '{
"title": "油は多めでないと",
"tags" : ["Ruby","家系ラーメン"],
"content": "久々に家系ラーメンを食べました\nやっぱり胃薬飲んでかえります",
"published_on": "2013-08-31T22:07:18+09:00"
}'
インデックスの表示
GET メソッドを指定するとインデックスが検索できます。
$ curl -XGET http://localhost:9200/blog/article/1
検索
作成したインデックスをもとに検索を行うことができます。
$ curl -XGET http://localhost:9200/blog/_search -d '{
"query" : {
"term" { "content": "ラーメン" }
}
}'
こんな感じで結果が返ります
{"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":0.057534903,"hits":[{"_index":"blog","_type":"article","_id":"UZZ-CFdLTmCW6FAnDJVzmg","_score":0.057534903, "_source" : {
"title": "増し増しに沈没",
"tags" : ["Ruby","ラーメン二郎"],
"content": "ラーメン二郎にチャレンジしました\n増し増しに撃沈\n胃薬飲んでかえります",
"published_on": "2013-08-31T22:07:18+09:00"
}}]}}
このラッパーとなるクラスが Tire です。
Tire
Ruby単体でも動作しますが、Railsと組み合わせた方が力を発揮しそうです。
インストール
$ gem install tire
Ruby単体での動作
最初に tire を読み込みます。
require 'rubygems'
require 'tire'
インデックスを作成・削除・更新
Tire.index 内のメソッドで行います。
Tire.index 'post_tire' do
delete
create
store title: "増し増しに沈没", tags: ["Ruby","ラーメン二郎"], content: "ラーメン二郎にチャレンジしました\n増し増しに撃沈\n胃薬飲んでかえります", published_on: Time.now
refresh
end
検索
前項のインデックスを作成した後に検索を行います。
s = Tire.search 'post_tire' do
query do
string "content:ラーメン"
end
end
s.results.each do |document|
puts "* title: #{document.title} content: #{ document.content } [tags: #{document.tags.join(', ')}]"
end
結果はこんな感じに出力されます。
* title: 増し増しに沈没 content: ラーメン二郎にチャレンジしました
増し増しに撃沈
胃薬飲んでかえります [tags: Ruby, ラーメン二郎]
次回は Rails との連携について書きたいと思います。