最近、バイト先でElasticsearchを触っている。
今まで、「記事」をついているタグ別に表示する機能を実装するのにacts-as-taggable-onというGemを使ってきた。これはRailsでは定番のGemらしくて、 確かにこいつを使えばタグというもので想像される機能をほぼ全部つけることができるので非常に便利。
しかし、何をするにもDBアクセスも多く重いという問題がある。タグを新しく付ける、加えるといったそんなに頻繁に発生するわけではない処理ではそこまで問題にならない。
しかし、記事を表示するときに同じタグの付いている記事をリコメンドする機能なんかをつけようとすると大変。リクエストされた記事と同じタグの付いている記事を検索する必要があるのだが、これがなかなか負荷がかかっていた。閲覧の方は頻度が高いので、緊急に高速化する必要が出てきた。
そこで使うのがElasticsearchである。Elasticsearch自体は全文検索エンジンだけれども、「単純に××というタグの付いた記事を全部とってくる」とかいう処理も高速に処理可能。超シンプルなテストで実験してみたら、acts-as-taggable-onよりも10~100倍早かった。
今までElasticsearchは組み込んではみたけれども使い物にならなくてやっぱりやめた、という経緯があるらしく、tireというgem経由でElasticsearchをRailsから利用しようとしていた痕跡が残っていた。
しかし現在はElasticsearch公式のGemが出ており、tireは役目を終えてretireという名前になっている。なのでまずやるべきだったのはtireではなくelasticsearch-rails、elasticsearch-modelを使うようにすること。これから導入するのであれば、この2つを入れればOKだろう。
elasticsearch-○○というgemはやたらいっぱいあるのだが、基本はこの2つがあれば十分なように感じる。RSpecを使うときにテスト用のElasticsearchサーバーを建てたい、なんてときに便利なelasticsearch-extensionsというやつもあるけど。
日本語でも検索できるようにするためにはkuromojiで形態素解析をかけるとよい。n-gramでいいというなら別にいいけど。
ここが結構ハマりどころなんだけれども、elasticsearchのバージョンとkuromojiプラグインのバージョンは厳密な対応関係があってこれを破ると全く動いてくれない。今後「インデックスが張れないよ~ ><」というエラーが出てきたらまずはじめに疑うべきはここ。ローカルでは動いたのにサーバーで/CIではエラーが出る、というときはローカルとリモートでelasticsearchとkuromojiプラグインのバージョンが違っていないかをチェックしよう。(TravisCIでテストが通らなくて困った困った…)
とりあえずこれでelasticsearchを使う準備はととのった。