はじめに
みなさんこんにちは、teratail 開発チームの本橋佑介です。
昨今のWebサービスでは、以前のようにユーザが努力をして興味のあるコンテンツを探すサービスから、キュレーションサービスのようにユーザの興味を分析し配信することが重要とされています。
以前からも、ユーザの動向を分析するために、開発者はさまざまな手段を用いてユーザの興味に合った情報を配信することを実現してきましたが、得られるデータがユーザのサービス内のアクティビティのみだったため、決して精度が高いものとは言えませんでした。
現在では、莫大で多様なデータを取得することが可能になったため、ユーザの興味に近い情報を分析することが可能になりました。そのため、データをそのまま蓄積するだけではなく、各データに属性や情報を付与するなど、高度で柔軟性の高い検索・分析が行える全文検索システムに注目が集まっています。
Luceneという全文検索エンジン(※ )を利用しているApacheライセンス下のSolrと、Elastic社の元でOSSとして開発されてるElasticsearchが多く採用されていますが、ここではFacebookやGitHubなどで利用され、teratailでも導入されているElasticsearchについて取り上げたいと思います。
Elasticsearchの特徴
Elasticsearchの最大の特徴として、以下の2つのキーワードがあります。
スケーラブルで柔軟な設計
クラスタ構成が前提で実装されているため、同一のクラスタ名で用意するだけでレプリカが自動で実行されます。また、データのマッピングを定義せずにデータの投入が可能なため、蓄積した後に利用したい形に変更することが可能です。
REST-API
設定ファイルも利用可能ですが、RESTインターフェースですべての入出力が可能です。HTTPで接続可能なので開発環境を選びません。
上記の特徴以外にも、Elastic社が提供している強力な可視化ツールであるKibana、Elasticsearchのセキュリティ管理をするShield、データの監視をするWatcherなど、さまざまなサービスが提供されています。
RDBMSとの対比
OracleやPostgreSQLなどのRDBMSとElasticsearchの違いはどこにあるのでしょうか。
データを蓄積するものとデータを取り出すものという思想の違いがありますが、一番大きいのはRDBMSは条件にマッチしたデータを正確に返す のと比べ、Elasticsearchは条件との関係性の高いデータを返す という点があります。
たとえば、賃貸物件検索などを行う場合、以下のような条件で検索することがよくあります。
RDBMSでこのQueryを流した場合、完全に一致したものを返すため、物件情報が存在しなかったら0件のデータを返しますが、Elasticsearchでは、たとえば駅から1.1kmであっても他の2件の条件が満たされていたら、そのデータを返します。
上記のようにデータの取り扱いも違いますが、構成を表す言葉も以下のように違っています。
Node = DBインスタンス
Cluster = Databaseクラスター
Index = Databaseスキーマ
Mapping Type = Table
検索結果の関連度
検索結果では、完全一致ではなく関連度の高いものを返すとありますが、関連度はどのように決定されているのでしょうか。
Elasticsearchの関連度にはスコアというものが設定されています。1ワードの検索ではこのスコアの算出にはTF/IDF(Term Frequency/Inverse Document Frequency)という考え方が採用されています。
たとえば、gihyo.jpのような記事サービスの詳細ページの文書が入ったtypeにElasticsearch
というワードを検索するクエリを流したとします。
この考えでは文書と検索ワードの関連度は、文書内でのワードの出現頻度で決定されます。また、関連度合いの重み付けとしてワードの短さというものも重要視されます。これは長い本文中に一度だけ引用として記載されたことよりも短いタイトル上に表記されたほうが検索ワードとの関連性が高いと判断することになります。
サービスでの活用事例
冒頭でも紹介したとおりElasticsearchは数多くの大規模サービスで採用されています。今回は私の開発しているteratailでの活用事例を一部紹介したいと思います。
ここでは質問詳細ページの「関連した質問」について紹介します。
まず、前提として質問のタイトル・技術分類を表すタグ・本文・回答本文を1つの文書として登録しています。表示されている情報を元にタグ情報と文書を検索ワードとしてMore Like This Queryを使用し、関連した質問を取得しています。類似文書を取得する方法としてはとても手軽で便利な仕組みです。
More Like This Queryはその名の通り、類似文書検索とよばれ「文書に似たものを探す」ものです。同じ語を多く含む文書を類似文書と定義します。これにより、表示されている質問と似た質問を表示し、ユーザの解決の手助けとなるようにしています。More Like This Queryには語の最大数や出現数の下限上限などさまざまなものを指定できます。teratailでは変数名など意味は無いが出現回数が多くなりがちなデータを除外するよう設定を変更してチューニングしています。
また、More Like This Queryを利用しない方法としては、Percolatorという通常とは逆の方向に文書から該当するクエリを抽出する仕組みを用いて文書内の重要な単語を集計し、それを元に類似文書を求めたり、機械学習モデルを作成する方法もあります。プロジェクトの大きさや必要とする類似度の精度を元に適したものを選択しましょう。
主なプラグインの紹介
ElasticsearchにはElastic社が提供するさまざまなプラグインが存在します。それらを用いることにより、全文検索がより柔軟にできたり、文書の分析を行いやすくすることなどさまざまなことが可能になります。
Watcher
Watcherプラグインはアラートを検知するプラグインです。indexに登録されている文書を監視しメールやslackなど定義したものに通知を行うことができます。また、関し履歴はindexにもなっているので、それ自体を参照することも可能です。
Shield
特に認証などがないElasticsearchの認証を管理できます。また、SSL暗号化やフィールドごとの権限制御が実現できます。
Marvel
Elasticsearchのクラスタのモニタリングが行えます。これは次に紹介するkibanaの上で動作します。複数のクラスタをリアルタイムで監視することができます。
Kibana
Elasticsearchの文書をシームレスに集計しグラフィカルに表示できます。Webサーバのアクセスログなど文書として保持し、アクセス解析結果を表示する際などによく利用されます。
Elastic社が提供している以外にも日本語の形態素解析を行う独自プラグインが存在し、また自分で作成することができます。
Elasticsearch 2.0.0
本稿執筆時点(2015/11/24)でElasticsearchの最新バージョンは2.0.0です。1系は1.7.3が最新です。2.0系で追加された機能で大きなものは以下のものです。
Pipeline Aggregations
さまざまな集計を行うAggregationの結果に対する計算を行う機能
Query/Filter merging
フィルタが廃止されすべてクエリに統合されました
Core Plugin
先に紹介したプラグインが公式にサポートされ、Elasticsearchのリリースと同じタイミングでリリースされることになります
Elasticsearch 2.1.0 2.0.1
本稿執筆中(2015/11/24)に2.1.0と2.0.1がリリースされたので、こちらも簡単に紹介します。
ベースとしているLuceneのバージョンが5.2.1から5.3.1に上がり、それに対応したものを2.1.0としているため、バージョンの違いが生まれています。また、このリリースで修正されたGeo Centroid Aggregationでは、位置情報による集計結果をエリアの中心地ではなく現実に存在するポイントに設定されることになります。この機能によって、より自然な情報の出力が可能になりました。
最後に
Elasticsearchの特徴からプラグインなどを紹介してきました本稿ですが、Elasticsearchの最も優れている点は、分析の柔軟性やその速度です。とても手軽に強力な機能を導入することが可能ですし、さらにもっと高度な利用も可能です。
私自身、こういった新しいサービスの導入調査を行うことが多いのですが、いつも思うのはリリースなどを読み新しい機能を追いかけることよりも、なぜこのような機能が生まれたのかなどの思想の部分を理解することが重要だと思っています。もちろんすべてが文書として残っているわけではないので大変困難ではあります。
読んでいただいた方にエンジニアとして基礎部分を固めるために、テクニックではなく概念の理解を意識できるよう本連載を続けていけるよう励みたいと思います。