Elastic Certified Engineer Exam対策 – Analyzer

Banner image for Elastic Training: instructor presenting at a chalkboard with the text 'Elastic Certified Engineer Exam 対策'. トレーニング

このブログの目的

本記事では、Elastic Certified Engineer Examの試験範囲である「Data Processing – Define and use multi-fields with different data types and/or analyzers」を対象に、ElasticsearchにおけるAnalyzerの基本を整理します。

Data Processing – Define and use multi-fields with different data types and/or analyzers

Analyzerは、全文検索を実現するために、文字列を検索しやすい単位へ分割・変換する仕組みです。試験では、Analyzerそのものの詳細な内部実装よりも、要件に応じて適切なAnalyzerを選択し、Mappingへ設定するとともに、Analyzerが全文検索へ与える影響を理解することが重要です。

また、multi-fieldsを利用して、同じ文字列Fieldを全文検索用のtext型と、完全一致検索・ソート・Aggregation用のkeyword型として使い分けられることも重要なポイントです。本記事では、Analyzerの役割や、Analyzerがtext型とkeyword型でどのように扱われるのか、Index AnalyzerとSearch Analyzerの使い分け、Mappingへの適用方法を中心に確認していきます。

なお、本記事では理解を深めるためにCustom Analyzerや日本語の形態素解析についても、理解を深めるために紹介します。ただし、これらは現在の試験範囲には含まれていないため、試験対策としては、適切なAnalyzerを選択し、Mappingへ設定できることを中心に学習してください。

試験情報は以下サイトで確認可能です。

Analyzerとは

Analyzerの役割

Analyzerは、Elasticsearchで全文検索(Full Text Search)を実現するための重要な仕組みです。検索対象となるテキストを、そのまま1つの文字列として扱うのではなく、検索しやすい単位(トークン)へ分割・変換する役割を担います。

例えば、「The Quick Brown Fox」という文字列をAnalyzerで処理すると、「the」「quick」「brown」「fox」のようなトークンへ変換されます。この変換処理により、大文字・小文字の違いや不要な文字の除去などを考慮した柔軟な全文検索が可能になります。

Elasticsearchでは、Analyzerはインデックス作成時だけでなく、検索時にも利用されます。インデックス時と検索時で同じルールでテキストを解析することで、「Quick」で検索した際に「quick」を含むドキュメントも正しくヒットさせることができます。

全文検索 = Full Text Searchとの関係

Full Text Search = 全文検索 とは、単なる文字列の完全一致ではなく、検索キーワードに関連する文書を柔軟に検索する仕組みです。そのため、検索対象となるテキストは、あらかじめ検索しやすい形式へ変換しておく必要があります。この変換処理を担うのがAnalyzerです。

例えば、”A quick brown fox jumps over the lazy dog.”という文章に対して”Quick fox jumps”と検索した場合、完全一致検索では一致しません。しかし、Analyzerによって文書と検索キーワードの両方がトークン化されることで、「quick」「fox」「jumps」という共通のトークンを基に検索が行われ、該当する文書をヒットさせることができます。

一方、完全一致検索で利用されるTerm QueryではAnalyzerは利用されません。そのため、全文検索を行うMatch QueryなどではAnalyzerが重要な役割を果たし、Term Queryとは動作が異なることを理解しておく必要があります。

Analyzerが適用されるField

Analyzerは、すべてのFieldに適用されるわけではありません。基本的には、Mappingでtext型として定義されたFieldに対して適用されます。text型は全文検索を目的としたFieldであり、インデックス作成時と検索時にAnalyzerによる解析が実行されます。

一方、keyword型FieldにはAnalyzerは適用されません。keyword型は値を1つの文字列として保持するため、トークン化は行われず、インデックスにはそのままの値が保存されます。そのため、ユーザーIDやメールアドレス、商品コード、タグなど、完全一致で検索したいデータに適しています。

また、1つのFieldに対してtext型とkeyword型の両方を持たせるMulti-fieldsもよく利用されます。この構成により、同じデータに対して全文検索と完全一致検索の両方を実現できます。

Index AnalyzerとSearch Analyzer

Elasticsearchでは、Analyzerはインデックス作成時だけでなく、検索時にも利用されます。それぞれで利用されるAnalyzerは、Index AnalyzerとSearch Analyzerと呼ばれます。

Index Analyzerは、ドキュメントをインデックスへ登録する際に実行されます。テキストをトークンへ分割・変換し、その結果がインデックスへ保存されます。一方、Search Analyzerは、検索クエリが実行された際に検索キーワードを解析するために利用されます。

通常は、インデックス作成時と検索時で同じAnalyzerが利用されますが、Mappingでsearch_analyzerを指定することで、検索時のみ別のAnalyzerを利用することもできます。例えば、インデックス作成時はSynonymを適用せず、検索時のみSynonymを適用するといった構成も可能です。

Elastic Docs > Manage data > The Elasticsearch data store > Text analysis > Configure text analysis > Specify an analyzer

Analyzerの構成

Analyzerを構成する3つの要素

前章では、Analyzerが全文検索を実現するために、テキストを検索しやすい形へ変換する仕組みであることを説明しました。では、Analyzerはどのようにして文字列を変換しているのでしょうか。

Analyzerは、単一の機能ではなく、複数のコンポーネントを組み合わせて構成されています。具体的には、Character Filter、Tokenizer、Token Filterの3つの要素で構成され、それぞれが異なる役割を担っています。

  • Character Filter:文字列の前処理を行う
  • Tokenizer:文字列をトークンへ分割する
  • Token Filter:生成されたトークンを加工・変換する

これら3つの要素は、必ず「Character Filter → Tokenizer → Token Filter」の順番で実行されます。例えば、HTMLタグを除去した後に単語へ分割し、その後すべて小文字へ変換するといった一連の処理が、この順序で行われます。

Character Filter

Character Filterは、Analyzerの最初に実行されるコンポーネントです。Tokenizerで文字列をトークンへ分割する前に、入力されたテキストに対して前処理を行います。例えば、不要な文字の除去や特定の文字列の置換などを行うことで、その後のトークン化を適切に実施できるようにします。

代表的なCharacter Filterには、次のようなものがあります。

  • HTML Strip:HTMLタグを除去する
  • Mapping Character Filter:指定した文字列を別の文字列へ置換する
  • Pattern Replace Character Filter:正規表現を利用して文字列を置換する

これらを利用することで、検索対象となるテキストを要件に合わせて正規化できます。

例えば、HTML形式の文章を検索対象とする場合、HTMLタグをそのままインデックスへ登録すると、検索精度に影響を与える可能性があります。そのような場合は、HTML Strip Character Filterを利用することで、HTMLタグを除去したテキストをTokenizerへ渡すことができます。

Elastic Docs > Elasticsearch > Text analysis components > Character filter reference

Tokenizer

Tokenizerは、Character Filterによる前処理が終わった文字列を、検索可能な単位である「トークン」へ分割するコンポーネントです。Analyzerの中心となる要素であり、どのような単位でテキストを分割するかによって、検索結果に大きな影響を与えます。

代表的なTokenizerには、次のようなものがあります。

  • Standard Tokenizer:単語や句読点などを考慮し、一般的な文章を単語単位で分割する
  • Whitespace Tokenizer:空白文字を区切りとして分割する
  • Keyword Tokenizer:文字列を分割せず、1つのトークンとして扱う
  • Ngram Tokenizer:文字列を指定した文字数ごとに分割し、部分一致検索を実現する
  • Edge Ngram Tokenizer:文字列の先頭から指定した文字数ごとに分割し、インクリメンタルサーチなどで利用される

例えば、「The Quick Brown Fox」という文字列をStandard Tokenizerで処理すると、「The」「Quick」「Brown」「Fox」の4つのトークンへ分割されます。一方、Keyword Tokenizerを利用した場合は、文字列全体が1つのトークンとして扱われます。

Elastic Docs > Reference > Elasticsearch > Text analysis components > Tokenizer reference

Token Filter

Token Filterは、Tokenizerによって生成されたトークンを加工・変換するコンポーネントです。Tokenizerは文字列をトークンへ分割する役割を担いますが、Token Filterはそのトークンに対して大文字・小文字の変換や不要な単語の除去、類義語への展開などを行い、検索精度を向上させます。

代表的なToken Filterには、次のようなものがあります。

  • Lowercase Filter:トークンを小文字へ変換する
  • Stop Filter:a、the、isなどのストップワードを除去する
  • Synonym Filter:類義語を追加・展開する
  • Stemmer Filter:単語を語幹へ変換する

例えば、「Quick」「Brown」「Fox」というトークンにLowercase Filterを適用すると、「quick」「brown」「fox」へ変換されます。また、Stop Filterを利用することで、検索に不要な単語を除去し、検索効率や検索精度を向上させることができます。

Elastic Docs > Reference > Elasticsearch > Text analysis components > Token filter reference

Analyzerの処理の流れ

ここまで説明したように、AnalyzerはCharacter Filter、Tokenizer、Token Filterの3つのコンポーネントで構成されます。これらは独立して動作するのではなく、決められた順序で連続して実行されることで、入力されたテキストを検索しやすい形へ変換します。

Analyzerの処理順序は、次のとおりです。

  1. Character Filter:文字列の前処理を行う
  2. Tokenizer:文字列をトークンへ分割する
  3. Token Filter:生成されたトークンを加工・変換する

例えば、「<b>The Quick Brown Fox</b>」という文字列に対して、HTML Strip Character Filter、Standard Tokenizer、Lowercase Filterを適用した場合、処理は次のように進みます。

処理結果
入力<b>The Quick Brown Fox</b>
Character FilterThe Quick Brown Fox
TokenizerThe Quick Brown Fox
Token Filterthe quick brown fox

このように、各コンポーネントが順番に処理を行うことで、検索に適したトークンが生成されます。どれか1つでも異なる設定にすると、最終的に生成されるトークンも変化するため、検索結果にも影響を与えます。

Analyzerの実装と確認

4.1 Custom Analyzerの作成

Custom AnalyzerはElastic Certified Engineer Examの試験範囲からは除外されています

これまで説明したように、AnalyzerはCharacter Filter、Tokenizer、Token Filterを組み合わせて構成されます。ElasticsearchにはStandard Analyzerなどの組み込みAnalyzerが用意されていますが、要件に応じて独自のAnalyzer(Custom Analyzer)を作成することもできます。

Custom Analyzerは、インデックス作成時のsettings.analysisで定義します。Analyzer名を指定した上で、利用するTokenizerやToken Filter、必要に応じてCharacter Filterを組み合わせることで、用途に応じたAnalyzerを構成できます。

例えば、Standard Tokenizerで単語へ分割した後、Lowercase Filterですべて小文字へ変換し、Stop Filterで不要な単語を除去するといったAnalyzerを作成できます。このように、各コンポーネントを自由に組み合わせることで、検索要件に適したAnalyzerを実装できます。

次の例では、custom_analyzerという名前のCustom Analyzerを作成しています。

PUT sample-index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "custom_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "stop"
          ]
        }
      }
    }
  }
}

このCustom Analyzerを次のテキストに適用し、Character Filter、Tokenizer、Token Filterによってトークンがどのように変換されるのか確認してみましょう。

The Elasticsearch Certified Engineer exam covers indexing, searching, and data analysis in the Elastic Stack.
処理結果
入力The Elasticsearch Certified Engineer exam covers indexing, searching, and data analysis in the Elastic Stack.
Standard TokenizerThe / Elasticsearch / Certified / Engineer / exam / covers / indexing / searching / and / data / analysis / in / the / Elastic / Stack
Lowercase Filterthe / elasticsearch / certified / engineer / exam / covers / indexing / searching / and / data / analysis / in / the / elastic / stack
Stop Filterelasticsearch / certified / engineer / exam / covers / indexing / searching / data / analysis / elastic / stack

このように、Custom AnalyzerはCharacter Filter、Tokenizer、Token Filterを自由に組み合わせることで、検索要件に応じたテキスト解析を実現できます。次節では、作成したAnalyzerをMappingへ適用する方法について見ていきます。

Mappingへの適用

Custom Analyzerを作成しただけでは、そのAnalyzerは検索には利用されません。実際にAnalyzerを利用するためには、Mappingで対象となるtext型FieldへAnalyzerを設定する必要があります。

Analyzerは、Mappingのanalyzerパラメータで指定します。また、検索時のみ別のAnalyzerを利用したい場合は、search_analyzerパラメータを併せて指定できます。

次の例では、第4.1で作成したcustom_analyzermessageフィールドへ適用しています。

PUT sample-analyzer-index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "custom_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "stop"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "message": {
        "type": "text",
        "analyzer": "custom_analyzer"
      }
    }
  }
}

検索時のみ別のAnalyzerを利用したい場合は、search_analyzerを指定します。

PUT sample-analyzer-index-ver2
{
  "settings": {
    "analysis": {
      "analyzer": {
        "custom_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "stop"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "message": {
        "type": "text",
        "analyzer": "custom_analyzer",
        "search_analyzer": "standard"
      }
    }
  }
}

この例では、インデックス作成時はcustom_analyzer、検索時はstandard Analyzerが利用されます。このように、インデックス時と検索時で異なるAnalyzerを利用することで、検索要件に応じた柔軟な検索を実現できます。

_analyze APIによる動作確認

Analyzerを作成・設定した後は、意図したとおりにテキストが解析されていることを確認することが重要です。その際に利用するのが、_analyze APIです。_analyze APIを利用すると、指定したAnalyzerによってテキストがどのようなトークンへ変換されるのかを確認できます。

例えば、第4.1で作成したcustom_analyzerを利用して、テキストを解析するには次のように実行します。

POST sample-index/_analyze
{
  "analyzer": "custom_analyzer",
  "text": "The Elasticsearch Certified Engineer exam covers indexing, searching, and data analysis in the Elastic Stack."
}

実行すると、Analyzerによって生成されたトークンが返却されます。これにより、想定どおりにトークン化や小文字化、ストップワードの除去などが行われていることを確認できます。

また、_analyze APIではAnalyzerだけでなく、TokenizerやToken Filterを個別に指定して動作を確認することもできます。

例えば、Standard Tokenizerのみを利用して解析する場合は、次のように実行します。

POST _analyze
{
  "tokenizer": "standard",
  "text": "The Elasticsearch Certified Engineer exam covers indexing, searching, and data analysis in the Elastic Stack."
}

このように、_analyze APIはAnalyzerや各コンポーネントの動作を個別に検証できるため、Analyzerの設計やデバッグに役立ちます。

Analyzerの動作確認

ここまでで、Custom Analyzerの作成方法とMappingへの適用方法、さらに_analyze APIによる解析結果の確認方法について説明しました。最後に、実際にドキュメントを登録し、全文検索を実行することで、Analyzerが検索結果にどのような影響を与えるのかを確認してみましょう。

まず、前節までで作成したsample-analyzer-indexへドキュメントを登録します。

POST sample-analyzer-index/_doc
{
  "message": "The Elasticsearch Certified Engineer exam covers indexing, searching, and data analysis in the Elastic Stack."
}

続いて、messageフィールドに対してMatch Queryを実行します。

GET sample-analyzer-index/_search
{
  "query": {
    "match": {
      "message": "Elasticsearch analysis"
    }
  }
}

検索キーワードである「Elasticsearch analysis」は、検索時にAnalyzerによってトークン化されます。また、インデックス作成時にも同じAnalyzerで解析されたトークンが保存されているため、該当するドキュメントがヒットします。

一方、termクエリを利用した場合はAnalyzerによる解析は行われず、インデックスへ保存されているトークンとの完全一致で検索されます。そのため、全文検索を行う場合は、matchクエリなどAnalyzerを利用するクエリを使用することが重要です。

代表的なAnalyzer

ここまで、Analyzerの役割や構成、Custom Analyzerの作成方法について説明してきました。本章では、Elasticsearchにあらかじめ用意されている代表的なAnalyzerを紹介します。これらのAnalyzerは、Character Filter、Tokenizer、Token Filterを適切に組み合わせた組み込みAnalyzerであり、多くの検索システムでそのまま利用されています。

代表的なAnalyzerには、次のようなものがあります。

Analyzer主な用途
Standard Analyzer一般的な全文検索
Keyword Analyzer商品コードやIDなどの完全一致検索
Language Analyzer英語や日本語など、言語特性を考慮した全文検索
Whitespace Analyzer空白文字で区切られたテキストの解析

利用するAnalyzerによって、生成されるトークンや検索結果は大きく変わります。そのため、検索対象となるデータの特性や検索要件に応じて、適切なAnalyzerを選択することが重要です。

次節以降では、それぞれのAnalyzerの特徴や利用シーンについて見ていきます。

Standard Analyzer

Standard Analyzerは、ElasticsearchでデフォルトのAnalyzerとして利用される最も一般的なAnalyzerです。英語をはじめとする自然言語の全文検索を目的として設計されており、多くのユースケースでそのまま利用できます。特別な要件がない限り、まずStandard Analyzerの利用を検討するとよいでしょう。

Standard Analyzerは、内部でStandard Tokenizerを使用して単語単位にトークン化を行い、その後Lowercase Filterによってすべてのトークンを小文字へ変換します。また、デフォルトではStop Filterは利用されません。そのため、「The」と「the」のような大文字・小文字の違いを吸収しつつ、一般的な文章を適切に解析できます。

例えば、次のように_analyze APIを実行します。

POST _analyze
{
  "analyzer": "standard",
  "text": "Full text search helps users find relevant documents quickly and accurately across large datasets while improving the overall search experience."
}

実行すると、次のようなトークンが生成されます。

このように、Standard Analyzerは文章を単語単位へ分割し、大文字・小文字を正規化したトークンを生成します。全文検索では最も利用頻度の高いAnalyzerであり、検索対象が一般的な文章である場合に適しています。

Elastic Docs > Reference > Elasticsearch > Text analysis components > Analyzer reference > Standard

Keyword Analyzer

Keyword Analyzerは、入力された文字列を分割せず、1つのトークンとして扱うAnalyzerです。他のAnalyzerのように単語へ分割したり、小文字へ変換したりすることはなく、入力された文字列をそのまま保持します。そのため、商品コードやユーザーID、メールアドレスなど、文字列全体を1つの値として扱いたい場合に適しています。

Keyword Analyzerは、内部でKeyword Tokenizerを利用しており、Token Filterを持ちません。そのため、入力された文字列は一切加工されず、そのまま1つのトークンとして生成されます。

実務では、商品コードやユーザーIDなど文字列全体を1つの値として扱いたい場合は、keyword型を利用するケースが一般的です。keyword型は内部的にKeyword Analyzer相当の動作を行うため、Keyword Analyzerを明示的に指定する機会は多くありません。本節では、Keyword Analyzerの動作を理解することで、keyword型がどのように文字列を扱っているのかを確認します。

例えば、次のように_analyze APIを実行します。

POST _analyze
{
  "analyzer": "keyword",
  "text": "EMP-2026-0001"
}

実行すると、次のようなトークンが生成されます。

一方、文章を入力した場合でも、単語へ分割されることはありません。

POST _analyze
{
  "analyzer": "keyword",
  "text": "Full text search helps users find relevant documents."
}

実行結果は次のようになります。

このように、Keyword Analyzerは入力された文字列全体を1つのトークンとして扱います。そのため、全文検索には適していませんが、商品コードや注文番号、メールアドレス、タグなど、値全体で完全一致検索を行いたいデータに適しています。

Elastic Docs > Reference > Elasticsearch > Text analysis components > Analyzer reference > Keyword

Whitespace Analyzer

Whitespace Analyzerは、空白文字(Whitespace)を区切り文字としてトークン化を行うAnalyzerです。内部ではWhitespace Tokenizerを利用しており、文字列を空白で分割するだけのシンプルなAnalyzerです。Standard Analyzerのような句読点や記号を考慮した解析や、小文字への変換は行われません。

Whitespace Analyzerの特徴は、空白文字のみを区切りとして扱う点です。そのため、ハイフンやカンマなどの記号を含む文字列は、そのまま1つのトークンとして保持されます。また、大文字・小文字も区別されるため、必要に応じてLowercase Filterなどを組み合わせたCustom Analyzerとして利用されることもあります。

例えば、次のように_analyze APIを実行します。

POST _analyze
{
  "analyzer": "whitespace",
  "text": "Version 8.18 includes full-text search, vector-search, and AI-powered ranking."
}

実行すると、次のようなトークンが生成されます。

Version
8.18
includes
full-text
search,
vector-search,
and
AI-powered
ranking.

Standard Analyzerでは「full-text」は「full」「text」のように分割されますが、Whitespace Analyzerでは空白のみを区切りとして扱うため、「full-text」は1つのトークンとして保持されます。同様に、「8.18」や「ranking.」もそのまま1つのトークンとなります。

このように、Whitespace Analyzerは余計な解析を行わず、空白による単純な分割だけを実施したい場合に適しています。ただし、一般的な全文検索ではStandard Analyzerの方が利用されることが多く、Whitespace Analyzerはログデータや設定ファイルなど、空白区切りのテキストをそのまま扱いたいケースで利用されます。

Elastic Docs > Reference > Elasticsearch > Text analysis components > Analyzer reference > Whitespace

Language Analyzer

Language Analyzerは、英語や日本語、フランス語など、各言語の特性を考慮してテキストを解析するAnalyzerです。Standard Analyzerが一般的なトークン化を行うのに対し、Language Analyzerは言語ごとの文法や語形変化を考慮した解析を行うため、より自然な全文検索を実現できます。

例えば、英語向けのenglish Analyzerでは、不要な単語(Stop Words)の除去や、単語を語幹へ変換するステミング(Stemming)が行われます。そのため、「running」「runs」「ran」のような異なる表記も、共通の語幹として扱うことができます。

例えば、次のように_analyze APIを実行します。

POST _analyze
{
  "analyzer": "english",
  "text": "The runners are running quickly because they want to finish the race before sunset."
}

実行すると、次のようなトークンが生成されます。

この例では、「the」「are」「they」「to」などのストップワードが除去され、「runners」は「runner」、「running」は「run」へ変換されています。また、「quickly」や「before」も語幹へ変換され、単語の表記ゆれを吸収できることが分かります。

Language Analyzerは、英語だけでなく、ドイツ語、フランス語、スペイン語など、多くの言語向けに用意されています。検索対象となる言語に適したAnalyzerを利用することで、語形変化や不要な単語を考慮した、より精度の高い全文検索を実現できます。

Elastic Docs > Reference > Elasticsearch > Text analysis components > Analyzer reference > Language

日本語の形態素解析

(1) 日本語では形態素解析が必要

これまで紹介したStandard AnalyzerやEnglish Analyzerは、主に空白で単語が区切られる言語を対象としています。一方、日本語には英語のような単語間の空白が存在しないため、同じ方法では適切に単語を抽出できません。

例えば、「私は昨日東京でラーメンを食べました」という文章は、人間であれば「私」「昨日」「東京」「ラーメン」「食べました」といった単語に自然に分けて理解できます。しかし、コンピュータは単語の境界を判断できないため、適切な解析を行わなければ全文検索の精度が低下してしまいます。

このような日本語特有の課題を解決するために利用されるのが「形態素解析」です。形態素解析では、文章を意味を持つ最小単位(形態素)へ分割し、検索に適したトークンを生成します。これにより、「東京」や「食べる」といった単語単位で検索できるようになり、日本語でも高精度な全文検索を実現できます。

Elasticsearchでは、日本語の形態素解析を行うために、Analysis Kuromoji Pluginが提供されています。Kuromojiは日本語向けのLanguage Analyzerとして利用され、文章を単語単位へ分割するだけでなく、品詞や活用形を考慮した解析も行います。日本語で全文検索を実装する場合は、基本的にKuromojiを利用することになります。

まずは、通常のstandard analyzerで日本を解析してみます。

POST _analyze
{
  "analyzer": "standard",
  "text": "私は昨日東京駅でラーメンを食べました。"
}

結果

{
  "tokens": [
    {
      "token": "私",
      "start_offset": 0,
      "end_offset": 1,
      "type": "<IDEOGRAPHIC>",
      "position": 0
    },
    {
      "token": "は",
      "start_offset": 1,
      "end_offset": 2,
      "type": "<HIRAGANA>",
      "position": 1
    },
    {
      "token": "昨",
      "start_offset": 2,
      "end_offset": 3,
      "type": "<IDEOGRAPHIC>",
      "position": 2
    },
    {
      "token": "日",
      "start_offset": 3,
      "end_offset": 4,
      "type": "<IDEOGRAPHIC>",
      "position": 3
    },
    {
      "token": "東",
      "start_offset": 4,
      "end_offset": 5,
      "type": "<IDEOGRAPHIC>",
      "position": 4
    },
    {
      "token": "京",
      "start_offset": 5,
      "end_offset": 6,
      "type": "<IDEOGRAPHIC>",
      "position": 5
    },
    {
      "token": "駅",
      "start_offset": 6,
      "end_offset": 7,
      "type": "<IDEOGRAPHIC>",
      "position": 6
    },
    {
      "token": "で",
      "start_offset": 7,
      "end_offset": 8,
      "type": "<HIRAGANA>",
      "position": 7
    },
    {
      "token": "ラーメン",
      "start_offset": 8,
      "end_offset": 12,
      "type": "<KATAKANA>",
      "position": 8
    },
    {
      "token": "を",
      "start_offset": 12,
      "end_offset": 13,
      "type": "<HIRAGANA>",
      "position": 9
    },
    {
      "token": "食",
      "start_offset": 13,
      "end_offset": 14,
      "type": "<IDEOGRAPHIC>",
      "position": 10
    },
    {
      "token": "べ",
      "start_offset": 14,
      "end_offset": 15,
      "type": "<HIRAGANA>",
      "position": 11
    },
    {
      "token": "ま",
      "start_offset": 15,
      "end_offset": 16,
      "type": "<HIRAGANA>",
      "position": 12
    },
    {
      "token": "し",
      "start_offset": 16,
      "end_offset": 17,
      "type": "<HIRAGANA>",
      "position": 13
    },
    {
      "token": "た",
      "start_offset": 17,
      "end_offset": 18,
      "type": "<HIRAGANA>",
      "position": 14
    }
  ]
}

実行結果を見ると、日本語は適切な単語単位ではなく、漢字は1文字ごと、ひらがなも1文字ごとに分割されていることが分かります。一方、カタカナは「ラーメン」のように1つの単語として扱われています。これはStandard Analyzerが日本語の文法や単語境界を理解しているわけではなく、Unicodeの文字種(漢字・ひらがな・カタカナなど)に基づいてトークン化しているためです。そのため、「昨日」や「東京駅」、「食べました」といった意味のある単語として認識できず、日本語の全文検索には適していません。

plugin 確認コマンド

以下は、利用環境でinstallされているpluginを確認するコマンドです。

日本語形態素解析 kuromoji が入っていない環境の場合、次節の手順を参考に、kuromojiをinstallしてください。

GET _nodes/plugins

次節では、Analysis Kuromoji Pluginのインストール方法について確認します。

(2) analysis-kuromojiプラグインのインストール

日本語の形態素解析を行うには、Analysis Kuromoji Pluginを利用する必要があります。Self-managed環境では標準ではインストールされていないため、各ElasticsearchノードへPluginを追加します。

本記事の主旨からは外れるため、pluginのインストール手順については簡単に紹介するに留めます。

<aside>

Analysis Kuromoji Pluginを加えたコンテナの作成手順

Docker環境では、コンテナ内へ手動でPluginをインストールしても、コンテナを再作成するとPluginは失われます。そのため、ここではAnalysis Kuromoji Pluginを組み込んだElasticsearchコンテナを作成する手順を紹介します。

【1】 “Dockerfile”を作成し、”docker-compose.yml” と同一階層に配備

“Dockerfile”ファイルの中身

FROM docker.elastic.co/elasticsearch/elasticsearch:9.3.3

RUN bin/elasticsearch-plugin install --batch analysis-kuromoji

【2】 docker-compose.ymlを修正

before

services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:9.3.3
    container_name: elasticsearch_933

after

elasticsearch:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: elasticsearch_933
  

【3】コンテナ再作成

nerdctl compose -f docker-compose.yml down
nerdctl compose build
nerdctl compose -f docker-compose.yml up -d

インストール後は、再度GET _nodes/pluginsを実行し、analysis-kuromojiが含まれていることを確認しましょう。確認できれば、日本語形態素解析を利用する準備は完了です。

次節では、Kuromoji Analyzerを利用して日本語の文章を解析し、Standard Analyzerとの違いを確認します。

(3) Kuromoji Analyzerを利用した解析

Analysis Kuromoji Pluginのインストールが完了したら、実際にKuromoji Analyzerで日本語の文章を解析してみましょう。前節ではStandard Analyzerを利用した結果、漢字やひらがなが文字単位で分割され、日本語の全文検索には適していないことを確認しました。一方、Kuromoji Analyzerは日本語の形態素解析を行い、意味のある単語単位へトークン化できます。

まずは、前節と同じ文章を対象に、Kuromoji Analyzerを利用して解析します。

POST _analyze
{
  "analyzer": "kuromoji",
  "text": "私は昨日東京駅でラーメンを食べました。"
}

実行すると、Standard Analyzerとは異なる解析結果が返却されます。

環境やElasticsearchのバージョン、Kuromojiの辞書バージョンによって、トークンの分割結果や活用語の扱いが一部異なる場合がありますが、「昨日」「東京」「ラーメン」といった意味のある単語単位で解析される点は共通しています。

Standard Analyzerでは「昨」「日」「東」「京」のように文字単位へ分割されていましたが、Kuromoji Analyzerでは日本語の文法や単語境界を考慮した形態素解析が行われます。そのため、日本語の全文検索では、検索精度を大きく向上させることができます。

実践問題

Problem 1

Create an index that meets the following requirements.

  • Index name: exam-analyzer-basic
  • Create a field named title of type text.
  • Configure the title field to use the standard analyzer.
  • Create a field named product_id of type keyword.

Write the request required to create this index.

Answer

PUT exam-analyzer-basic
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "standard"
      },
      "product_id": {
        "type": "keyword"
      }
    }
  }
}

解説

  • title フィールドは全文検索を目的とした text 型として定義し、standard Analyzerを指定しています。
  • analyzertext 型のFieldに対して指定し、インデックス作成時および検索時のテキスト解析に利用されます(search_analyzer を指定しない場合)。
  • product_id は識別子を保持するための keyword 型として定義しています。keyword 型はAnalyzerによるトークン化を行わず、完全一致検索やソート、Aggregationなどに利用されます。
  • Elastic Certified Engineer Examでは、text 型と keyword 型の使い分け、および analyzer をMappingへ適切に定義できることが重要です。

Problem 2

Create an index that meets the following requirements.

  • Index name: exam-multifield-analyzer
  • Create a field named name of type text.
  • Configure the name field to use the standard analyzer.
  • Add a multi-field named name.keyword of type keyword.

Write the request required to create this index.

Answer

PUT exam-multifield-analyzer
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "standard",
        "fields": {
          "keyword": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

解説

  • name name フィールドは text 型として定義し、全文検索用に standard Analyzerを指定しています。
  • name.keyword name.keywordkeyword 型のmulti-fieldとして定義しているため、完全一致検索、ソート、Aggregationなどに利用できます。
  • multi-fieldsの目的 multi-fieldsを利用することで、1つの文字列Fieldを全文検索用(text)と完全一致検索用(keyword)の両方で利用できます。

Problem 3

Create an index that meets the following requirements.

  • Index name: exam-search-analyzer
  • Create a field named description of type text.
  • Configure the index-time analyzer as standard.
  • Configure the search-time analyzer as whitespace.

Write the request required to create this index.

Answer

PUT exam-search-analyzer
{
  "mappings": {
    "properties": {
      "description": {
        "type": "text",
        "analyzer": "standard",
        "search_analyzer": "whitespace"
      }
    }
  }
}

解説

  • analyzer インデックス作成時に利用されるAnalyzerを指定します。この例では、description フィールドの値は standard Analyzerで解析されてインデックスされます。
  • search_analyzer 検索時に利用されるAnalyzerを指定します。この例では、検索クエリの文字列は whitespace Analyzerで解析されます。
  • analyzerとの関係 search_analyzer を指定しない場合は、analyzer に指定したAnalyzerが検索時にも利用されます。

Elastic社が提供する無料Hands-on Trainingで理解を深めよう

ここまで、Analyzerの役割や、代表的なAnalyzerの特徴、Mappingへの適用方法について学習してきました。Elastic Certified Engineer Examでは、Custom Analyzerや日本語の形態素解析の詳細な知識が問われることはありません。試験では、要件に応じて適切な既存のAnalyzerを選択し、text型Fieldへ適用できることや、_analyze APIを利用してAnalyzerの動作を確認できることが重要になります。

さらに理解を深めたい方には、Elastic社が無償で提供している「Elasticsearch Engineer On-Demand」のHands-on Trainingがおすすめです。本トレーニングでは、Analyzerの基本的な仕組みや、標準で提供されるAnalyzerの使い分け、Mappingへの適用方法、_analyze APIによる動作確認などを、実際にElasticsearchを操作しながら学習できます。

本記事とHands-on Trainingを併用することで、代表的なAnalyzerの特徴や適用方法を確実に理解できるようになります。Elastic Certified Engineer Examでは、要件に応じて適切なAnalyzerを選択・設定できることが重要ですので、Hands-on Trainingも活用しながら実際に手を動かして学習することをおすすめします。

Elastic Cloud アカウント作成

Elastic Training

Elastic Learning Portal

試験で問われるポイント

  • text型FieldにAnalyzerを適用できること Analyzerは主に text 型Fieldに適用されます。要件に従い、Mappingで analyzer を指定できることが重要です。
  • multi-fieldsでtext型とkeyword型を使い分けられること 1つのFieldを全文検索用の text 型、完全一致・ソート・Aggregation用の keyword 型として定義できることが問われます。
  • Index AnalyzerとSearch Analyzerを使い分けられること インデックス時は analyzer、検索時は search_analyzer を指定できます。検索要件に応じて、適切にMappingへ定義できるようにしておきましょう。

本記事では、Custom Analyzerや日本語の形態素解析についても解説していますが、これらは現在のElastic Certified Engineer Examの出題範囲には含まれていません。Custom Analyzerは以前は試験対象でしたが、試験範囲の変更に伴い対象外となりました。そのため、これらに関する難易度の高い問題が出題される可能性は低いと考えられます。試験対策としては、要件に応じて適切なAnalyzerを選択・設定できるようになっておけば十分でしょう。