Webアプリケーションで検索機能を実装するとき、RDBを用いることである程度の要件には対応できます。 ただ、あいまいな検索や複雑な条件による検索に対応しようとすると、RDBの場合パフォーマンスが非常に悪くなってしまいます。

こういったユースケースに適しているのがElasticsearchです。

この連載では、最終目標としてRuby on RailsとElasticsearchを用いて検索機能や関連記事機能を実装します。 今回はまずElasticsearchの概要についてまとめます。

Elasticsearchとは

Elasticsearchはドキュメント指向の全文検索エンジンです。 全文検索とは「複数のドキュメントの全文を対象に、特定の文字列を検索すること」で、JSON形式で表されたドキュメントに対する全文検索を実現するのがElasticsearchです。

ElasticsearchはJava製のソフトウェアで、プラグインをインストールすることで管理画面やドキュメントの解析機構を拡張することができます。

RDBとの比較

ElasticsearchとRDBとの違いは何なのでしょうか。

RDBはリレーションを正規化してデータを格納する、という性質を持ちます。 ここで、パフォーマンスを考慮した検索エンジンをつくろうとすると、必然的に非正規化することになります。 つまり、変更に弱くなってしまいます。

Elasticsearchの場合、ドキュメントを登録さえしておけば、あとは検索条件をJSON形式で表現することで検索することができます。 柔軟な検索条件に対応でき、かつ優れたパフォーマンスを出すことができます。

RDBは条件にマッチしたデータを返すのに対し、Elasticsearchは条件との関連の高いデータを返す、というのが大きな違いです。

構成要素の比較

RDBを構成する各要素について、Elasticsearchではどれに該当するかを見てみると、おおむね次のようになります。

RDB Elasticsearch
データベース インデックス
テーブル タイプ
レコード ドキュメント
カラム フィールド

実行例

ここで、Elasticsearchの動きを見てみるため、簡単な実行例を示します。

Elasticsearchは、目的のAPIに対してクエリを投げることで、結果をJSON形式で得ることができます。 たとえば登録されたすべてのドキュメントのtitleフィールドに「Rails」という文字列が含まれたものを取得するには、次のようなクエリを投げます。

GET _search
{
  "query": {
    "multi_match": {
      "query": "Rails",
      "fields": ["title"]
    }
  }
}

すると、次のような結果が得られます。 ここで注目すべきは_scoreで、単に文字列にマッチしただけでなく、そのドキュメントが文字列に対してどれくらい関連があるかを得ることができるのがRDBとの違いになります。

{
  "hits": {
    "hits": [
      {
        "_index": "articles",
        "_type": "article",
        "_id": "4",
        "_score": 0.9433406,
        "_source": {
          "title": "Docker ComposeでRuby+PostgreSQLによるRails開発環境を構築する方法"
        }
      },

      :
    ]
  }
}

Analyzerとは

もうひとつ、ElasticsearchではAnalyzerという概念が重要になってきます。

Analyzerとはインデックスを作成したりクエリを解析する際、データをどのように処理するかを定義したものです。 Analyzerは分割方法を定義するTokenizerと、分割後の文字列の整形処理を定義するFilterによって構成されます。

たとえば「Docker ComposeでRuby+PostgreSQLによるRails開発環境を構築する方法」という文字列を処理する際、まずTokenizerにより次のように分割され、

「Docker」「Compose」「で」「Ruby」「+」「PostgreSQL」「による」「Rails」「開発環境」「を」「構築」「する」「方法」

Filterにより助詞や記号を省略すると、

「Docker」「Compose」「Ruby」「PostgreSQL」「Rails」「開発環境」「構築」「方法」

というトークン群が得られます。 このトークン群を対象に検索が行なわれることになります。

こういったAnalyzerにはいくつかの種類があり、日本語用のAnalyzerとして代表的なものにkuromojiなどがあります。

参考記事

おわりに

Elasticsearchは多くの概念があり、とても1記事でまとめられませんが、簡単な機能を実装する上での基礎はこれくらいだと思います。

次回はDockerを用いてElasticsearchの開発環境を構築する方法についてまとめます。