satococoa's blog

主にサーバーサイド、Web 系エンジニアのブログです。Go, Ruby, React, GCP, ...etc.

Elasticsearch メモ

最近仕事で使いたいと思い、Elasticsearch で遊んだりしています。

$ brew install elasticsearch したらローカルで動いたのですが、そこから何すればいいのかさっぱりわからなかったので急がば回れということで本を読みました。

高速スケーラブル検索エンジン ElasticSearch Server

高速スケーラブル検索エンジン ElasticSearch Server

epub 版は以下から。

高速スケーラブル検索エンジン ElasticSearch Server【委託】 - 達人出版会

上記書籍は Elasticsearch 0.90.11 を元に書かれているので、実際に使う前に差分を公式のドキュメントで確認することをお勧めします。(そんなに大きくは変わってないですし、概念を学ぶにはぜひ書籍を)

雑多なメモ

elasticsearch-head

elasticsearch-head プラグインを使うとブラウザから elasticsearch の状態を見たり操作したりできます。これがないといちいち curlAPI を叩かないとクラスタの様子がわからない。

$ plugin -i mobz/elasticsearch-head # インストール
$ open http://localhost:9200/_plugin/head/

Rails から使うには

以下の gem を使う。ちなみに以前は tire という gem が主流のようでしたが、現在そのリポジトリkarmi/retire · GitHub という名前になって引退しています。(お茶目)

elasticsearch-model を使って、適切にインデックスの mapping をしたり query を組み立てたりすることができますが、デフォルトでは as_json メソッドの値をそのままインデックスに登録しているので、雑に使う分にはそれで十分かもしれません。

このへん。 https://github.com/elasticsearch/elasticsearch-rails/blob/4a61f1786696045561864567e0921db9b318aeaa/elasticsearch-model/lib/elasticsearch/model/serializing.rb#L26

あとは Article.search('title: hoge').records とかすれば、タイトルに hoge を含む検索結果に基づいて where id IN (1, 3, 4) みたいな SQL でレコードを取得できます。

ちゃんとインデックスを定義したい場合はモデルで mapping を定義して as_indexed_json をオーバーライドすることで Elasticsearch に登録する情報を定義したりできます。

クラスタリング

config/elasticsearch.yml の cluster.name が同じ elasticsearch の node がネットワーク上に存在すると、勝手にクラスタ化されます。すごいですね。 ちなみに Homebrew でインストールした場合は network.host: 127.0.0.1コメントアウトしないとクラスタに参加してくれませんでした。この辺検証するときは Vagrant でやるとか、公式からアーカイブ落としてきて起動するとかした方が楽かもしれません。

AWS 上で運用する際は以下のドキュメントが参考になります。 (node が参加するべきクラスタを EC2 API を叩いて探してくれたりする)

elasticsearch on ec2

ただ、このドキュメントだいぶ古いので注意が必要です。

シャード数はインデックス作成時にだけ指定できるみたいですが、レプリカ数はあとから足したり引いたりすることが可能なようです。 検索のパフォーマンスが足りなくなったなぁと思ったら増やす感じですね。

シャードやレプリカの配置は Elasticsearch に勝手配置してもらったり、任意の routing を定義したりもできるようです。

日本語全文検索

kuromoji というトークナイザーを使えば日本語での全文検索が可能です。

詳しくは以下。