RubyでElasticsearchを使ってみる

Elasticsearchをelasticsearch-rubyというgemを使って触ってみたのでメモしておこうと思います。

Elasticsearchのバージョンは7.1.1を使用しています。

接続

Elasticsearchへ接続します。

require 'elasticsearch'
client = Elasticsearch::Client.new log: true

localhost:9200以外で起動している場合には、以下のように指定することも可能です。

require 'elasticsearch'
client = Elasticsearch::Client.new url: 'http://example.com:9900', log: true

indexの作成

Elasticsearchではindex->type->document->fieldというようになっており、まずは一番上のindexから作っていきます。 リレーショナルデータベースで言うとindexがデータベース、documentがテーブル、fieldがカラムでtypeはデータベースとテーブルの中間といった感じでしょうか。

client.indices.create(index: 'japanese')

documentの作成

次にtypeを指定してdocumentを作成します。

client.create({index: 'japanese', type: 'books', id: 1, body: { title: '吾輩は猫である', text: '吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。'}})
client.create({index: 'japanese', type: 'books', id: 2, body: { title: '学問のすゝめ', text: '「天は人の上に人を造らず人の下に人を造らず」と言えり。されば天より人を生ずるには、万人は万人みな同じ位にして、生まれながら貴賤上下の差別なく、万物の霊たる身と心との働きをもって天地の間にあるよろずの物を資り、もって衣食住の用を達し、自由自在、互いに人の妨げをなさずしておのおの安楽にこの世を渡らしめ給うの趣意なり。'}})
client.create({index: 'japanese', type: 'books', id: 3, body: { title: '蜘蛛の糸', text: 'ある日の事でございます。御釈迦様は極楽の蓮池のふちを、独りでぶらぶら御歩きになっていらっしゃいました。池の中に咲いている蓮の花は、みんな玉のようにまっ白で、そのまん中にある金色の蕊からは、何とも云えない好い匂が、絶間なくあたりへ溢れて居ります。極楽は丁度朝なのでございましょう。'}})

検索

先程作成したデータに対して検索してみます。

client.search(index: 'japanese', type: 'books', body: {query: {match: {text: '極楽'}}})

typeは省略して横断的に検索することもできます。

ログ

今回の検索結果では「蜘蛛の糸」と「学問のすゝめ」が引っかかっていることが分かります。それぞれのマッチ度は蜘蛛の糸が2.135146、学問のすゝめが0.33668557になっていました。

2019-06-09 12:57:51 +0900: GET http://localhost:9200/japanese/books/_search [status:200, request:0.020s, query:0.004s]
2019-06-09 12:57:51 +0900: > {"query":{"match":{"text":"極楽"}}}
2019-06-09 12:57:51 +0900: < {"took":4,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":2,"relation":"eq"},"max_score":2.135146,"hits":[{"_index":"japanese","_type":"books","_id":"3","_score":2.135146,"_source":{"title":"蜘蛛の糸","text":"ある日の事でございます。御釈迦様は極楽の蓮池のふちを、独りでぶらぶら御歩きになっていらっしゃいました。池の中に咲いている蓮の花は、みんな玉のようにまっ白で、そのまん中にある金色の蕊からは、何とも云えない好い匂が、絶間なくあたりへ溢れて居ります。極楽は丁度朝なのでございましょう。"}},{"_index":"japanese","_type":"books","_id":"2","_score":0.33668557,"_source":{"title":"学問のすゝめ","text":"「天は人の上に人を造らず人の下に人を造らず」と言えり。されば天より人を生ずるには、万人は万人みな同じ位にして、生まれながら貴賤上下の差別なく、万物の霊たる身と心との働きをもって天地の間にあるよろずの物を資り、もって衣食住の用を達し、自由自在、互いに人の妨げをなさずしておのおの安楽にこの世を渡らしめ給うの趣意なり。"}}]}}

一致のみ検索

↑の例だと「学問のすゝめ」には極楽がないのに引っかかってきているので、一致した文章のみ検索するようにしてみます。

client.search(index: 'japanese', body: {query: {query_string: {default_field: 'text', query: '"極楽"'}}})

ログ

今回は「学問のすゝめ」は出ず、一致した文章のみ出ています。

2019-06-09 20:30:49 +0900: GET http://localhost:9200/japanese/_search [status:200, request:0.021s, query:0.002s]
2019-06-09 20:30:49 +0900: > {"query":{"query_string":{"default_field":"text","query":"\"極楽\""}}}
2019-06-09 20:30:49 +0900: < {"took":2,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":1,"relation":"eq"},"max_score":1.9517214,"hits":[{"_index":"japanese","_type":"books","_id":"3","_score":1.9517214,"_source":{"title":"蜘蛛の糸","text":"ある日の事でございます。御釈迦様は極楽の蓮池のふちを、独りでぶらぶら御歩きになっていらっしゃいました。池の中に咲いている蓮の花は、みんな玉のようにまっ白で、そのまん中にある金色の蕊からは、何とも云えない好い匂が、絶間なくあたりへ溢れて居ります。極楽は丁度朝なのでございましょう。"}}]}}

documentの削除

documentの削除にはidを指定して削除します。

client.delete({index: 'japanese', type: 'books', id: 3})

ログ

2019-06-09 21:56:46 +0900: DELETE http://localhost:9200/japanese/books/3 [status:200, request:0.012s, query:n/a]
2019-06-09 21:56:46 +0900: < {"_index":"japanese","_type":"books","_id":"3","_version":2,"result":"deleted","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":9,"_primary_term":1}