Elastic Certified Engineer Exam対策 – Runtime Field

Training banner for Elastic Certified Engineer Exam with Japanese text and a classroom icon over a tech background. トレーニング

1. このブログの目的

本ブログシリーズの目的は、Elastic Certified Engineer Examの合格に必要な知識と技術を体系的に習得することです。Elastic Certified Engineer Examでは、Elasticsearchの運用や設計に関する実践的なスキルが問われます。本記事は、Runtime Fieldに関する知識と実装スキルの習得を目的としており、Elastic社が公開している試験ガイドの以下の試験範囲に関連する内容を扱います。

Data Management – Define an index that satisfies a given set of requirements

Runtime Fieldは、検索時に動的なフィールドを生成できる機能です。試験では、Runtime Fieldの基本的な仕組みを理解するだけでなく、Mappingに定義する方法と検索時に定義する方法の違いを理解し、要件に応じたQuery DSLを作成できることが求められます。また、scriptを利用して既存フィールドの値を変換・補正するクエリを実装できることも重要なポイントです。

本記事では、Runtime Fieldの概要から2種類の定義方法、代表的なQuery DSLの実装例、試験で問われやすいポイントまでを解説します。実際にコマンドを実行しながら学習を進めることで、試験対策と実践的なスキルの習得を目指します。ぜひ実際に手を動かしながら学習を進め、試験合格につなげてください。

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

https://www.elastic.co/training/elastic-certified-engineer-exam

2. Runtime Fieldとは

Runtime Fieldは、インデックスに保存されているデータを変更せず、検索時に値を生成できるフィールドです。通常のフィールドはインデックス作成時に値が登録されますが、Runtime Fieldは検索実行時にscriptを実行し、その結果をフィールド値として扱います。

Elastic Certified Engineer Examでは、Runtime Fieldを「Mappingに定義する方法」と「runtime_mappingsで検索時に定義する方法」の違いを理解し、指定された要件に応じて正しいQuery DSLを作成できることが重要です。特に、既存フィールドの値をscriptで補正・変換し、検索やAggregationに利用する操作を押さえておく必要があります。

メリット・デメリット

Runtime Fieldの最大のメリットは、Reindexを実施することなく既存データに新しいフィールドを追加できる点です。また、既存フィールドの値やデータ型の補正、動的な計算結果の生成などを検索時に実現できるため、柔軟なデータ分析が可能になります。以下に、Runtime Fieldのメリットとデメリットについて箇条書きします。

メリット

  • Reindexを実施せずに新しいフィールドを追加できる
  • 既存フィールドの値やデータ型を検索時に補正できる
  • Query、Aggregation、Sortで利用できる
  • Mappingを変更せずにruntime_mappingsで一時的な分析を実施できる
  • 元データを変更せずに業務要件に応じたフィールドを柔軟に作成できる

デメリット

  • 検索時にスクリプトが実行されるため、検索性能が低下する可能性がある
  • 大量データに対する検索や集計ではCPU負荷が高くなる
  • search.allow_expensive_queries=false の環境では利用できない場合がある
  • 複雑なスクリプトは可読性や保守性を低下させる
  • 頻繁に利用する場合はIndexed Runtime Fieldの方が適している場合がある

3. Runtime Field 2つの定義方法

Runtime Fieldは「Mapping自体に組み込む形で定義する方法」「検索時にRuntime Fieldを定義する方法」の2つの定義方法があります。

3-1. Mappingに定義するRuntime Field

Runtime Fieldは、Mapping内のruntimeセクションに定義することで、Indexに対して永続的に利用できます。一度定義すると、そのIndexに対する検索やAggregationから毎回利用できるため、頻繁に使用するRuntime Fieldに適しています。

Mappingに定義したRuntime Fieldは、検索時に毎回scriptが実行される点はruntime_mappingsと同じですが、検索リクエストごとに定義する必要がありません。そのため、複数のユーザーやアプリケーションから共通して利用するフィールドを作成する場合に有効です。

また、Runtime FieldはIndex Templateにも定義できます。これにより、新しく作成されるIndexやData Streamに対してRuntime Fieldを自動的に適用できるため、運用管理を効率化できます。

以下は、サンプルデータとして用意されている”kibana_sample_data_ecommerce”インデックスに対して、order_dateから曜日を導き出すRuntime Fieldを追加する例です。

PUT kibana_sample_data_ecommerce/_mapping
{
  "runtime": {
    "full_day_name": {
      "type": "keyword",
      "script": {
        "source": """emit(doc['order_date'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT));
        """
      }
    }
  }
}

上記コマンドの説明

  • runtime
    Runtime Fieldを定義するセクションです。ここに定義されたフィールドは検索時に動的に生成されます。
  • full_day_name
    新しく追加するRuntime Field名です。検索やAggregationでは、この名前で参照します。
  • type: keyword
    生成される値のデータ型を指定しています。曜日名で集計できるようkeyword型を使用しています。Runtime Fieldで指定できるtypeは以下に記載があります。
https://www.elastic.co/docs/manage-data/data-store/mapping/map-runtime-field
types用途
booleantrue / false
date日付
double倍精度浮動小数
geo_point緯度経度
ipIPアドレス
keywordキーワード文字列
long整数
lookup他インデックス参照
composite複数値を返す Runtime Field
  • script
    Runtime Fieldの値を生成するPainless Scriptを定義します。
  • doc[‘order_date’].value
    order_dateフィールドの値を取得します。
  • dayOfWeekEnum
    日付から曜日情報を取得します。
  • getDisplayName(TextStyle.FULL, Locale.ROOT)
    曜日を「Monday」「Tuesday」のような完全な名称で取得します。
  • emit()
    Runtime Fieldとして返却する値を指定します。Runtime Fieldのscriptではemit()による値の出力が必須です。

このように定義されたfull_day_nameフィールド(曜日フィールド)は、通常のフィールドと同様に検索やAggregationで利用できます。

Runtime Field値を確認する

Runtime Fieldは_source領域には保存されません。そのため、Runtime Fieldを定義しただけでは通常の_search結果には表示されません。値を確認する場合は、fieldsパラメータで対象のRuntime Fieldを指定する必要があります。

GET kibana_sample_data_ecommerce/_search
{
    "_source":false,
    "fields": [
      "full_day_name"
    ]
}

KibanaでもRuntime Fieldを追加

Kibana > DiscoverからRuntime Fieldを定義することも可能です。Data View エリアの下矢印アイコンをクリックし”Add a field to this data view”を選択します。

runtime field名を入力し、Set valueにscriptを記述し、Saveすることで、このように、Kibana上からもRuntime Fieldを定義することが可能です。

Kibana > Discoverから登録するRuntime Fieldは、Data Viewに対するRuntime Fieldとなり、厳密にはIndexのMappingに定義するRuntime Fieldとは異なります。

3-2. runtime_mappingsによる検索時Runtime Field

Runtime Fieldは、Mappingに定義するだけでなく、Search APIのruntime_mappingsセクションで検索時に定義することもできます。この方法で定義したRuntime Fieldは、その検索リクエストの実行中のみ有効となり、IndexのMappingは変更されません。

runtime_mappingsは、一時的な分析や検証を行いたい場合に有効です。例えば、「特定の計算結果を確認したい」「新しいRuntime Fieldを試したい」「Mappingを変更せずに集計を実施したい」といったケースで利用できます。

以下は、order_dateから曜日を算出するRuntime Fieldを検索時に定義する例です。

# mappingに定義した"full_day_name"と重複しないように"full_day_name2"としています。
GET kibana_sample_data_ecommerce/_search
{
  "_source": false,
  "runtime_mappings": {
    "full_day_name2": {
      "type": "keyword",
      "script": {
        "source": """
          emit(doc['order_date'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT));
        """
      }
    }
  },
  "fields": [
    "full_day_name2"
  ]
}

この例では、”full_day_name2”フィールドは検索実行時にのみ生成されます。検索終了後もMappingには保存されず、他の検索リクエストから利用することはできません。

上記コマンドの説明

  • _source : false
    検索結果から_sourceを非表示にします。今回の目的はRuntime Fieldの値を確認することなので、不要な元データを除外しています。
  • runtime_mappings
    検索時にRuntime Fieldを定義するセクションです。この中で定義したRuntime Fieldは、その検索リクエストの実行中のみ有効となります。

この二つ以外の定義は、3.1と同様である為、説明を省きます。

4. Runtime Fieldの使用例

以下に、3パターンの使用例を記載します。

4.1 フィールドを後から追加する

既存データに新しい項目を追加したい場合に利用します。

以下のコマンドは、Kibanaが提供するサンプルData Streamである「kibana_sample_data_logs」に content_type というRuntime Fieldを追加しています。既存の request フィールドからリクエストされたコンテンツ種別を判定し、「download」「static」「page」のいずれかを動的に生成します。元データには存在しない業務上意味のあるフィールドを、Reindexすることなく後から追加できる点がRuntime Fieldの大きな利点です。

PUT kibana_sample_data_logs/_mapping
{
  "runtime": {
    "content_type": {
      "type": "keyword",
      "script": {
        "source": """
          if (doc['request.keyword'].size() == 0) return;

          String path = doc['request.keyword'].value;

          if (path.endsWith(".css")) {
            emit("static");
          } else if (path.endsWith(".zip")
                  || path.endsWith(".gz")
                  || path.endsWith(".deb")) {
            emit("download");
          } else {
            emit("page");
          }
        """
      }
    }
  }
}

4.2 フィールドの値や型を補正する

登録済みの値や型を検索時に補正したい場合に利用します。

以下のコマンドでは、Kibanaが提供するサンプルData Streamである「kibana_sample_data_logs」に対して、Runtime Field「status_code」を追加しています。このRuntime Fieldは、responseフィールドの値を参照し、HTTPレスポンスコードをlong型として扱えるようにするものです。

PUT kibana_sample_data_logs/_mapping
{
  "runtime": {
    "status_code": {
      "type": "long",
      "script": {
        "source": """
          if (doc['response.keyword'].size() != 0) {
            emit(Long.parseLong(doc['response.keyword'].value));
          }
        """
      }
    }
  }
}

4.3 フィールドを動的に計算する

既存フィールドを使って、新しい値を検索時に計算したい場合に利用します。例えば、以下のコマンドは、kibana_sample_data_ecommerceavg_price_per_item というRuntime Fieldを追加しています。既存の taxful_total_pricetotal_quantity を使い、注文ごとの1商品あたりの平均購入金額を検索時に動的に計算します。元データに存在しない計算結果を、Reindexせずに検索結果やAggregationで利用できます。

PUT kibana_sample_data_ecommerce/_mapping
{
  "runtime": {
    "avg_price_per_item": {
      "type": "double",
      "script": {
        "source": """
          if (doc['taxful_total_price'].size() != 0 && doc['total_quantity'].size() != 0 && doc['total_quantity'].value > 0) {
            emit(doc['taxful_total_price'].value / doc['total_quantity'].value);
          }
        """
      }
    }
  }
}

5. Runtime Fieldに関するその他のポイント

allow_expensive_queriesがfalseのとき

Runtime Fieldは検索時にスクリプトを実行して値を生成するため、Elasticsearchでは「高コストなクエリ(Expensive Query)」として扱われます。そのため、Cluster設定の search.allow_expensive_queriesfalse の場合、Runtime Fieldを利用した一部の検索や集計は Expensive Query と判定され、実行できなくなります。大規模データに対するRuntime Fieldの利用はCPU負荷が高くなるため、本番環境ではこの設定に注意が必要です。

Elastic Docs > Magane data > The Elasticsearch data store > Mapping > Runtime fields

https://www.elastic.co/docs/manage-data/data-store/mapping/runtime-fields

Elastic Docs > Explore and analyze > Querying and filtering > Query languages > Query DSL

https://www.elastic.co/docs/explore-analyze/query-filter/languages/querydsl#query-dsl-allow-expensive-queries

Runtime FieldとIndexed Runtime FieldとScript Field

Rutime Fieldと似た機能として、Indexed Runtime FieldとScript Fieldについて違いを明確にしておきます。

Runtime Field

Runtime Fieldは、検索時にスクリプトを実行して値を動的に生成する仮想フィールドです。インデックスには保存されないためストレージ消費を抑えられますが、クエリや集計の実行時に毎回計算が発生します。既存データを再インデックスすることなく、新しいフィールドを追加したい場合や、一時的な分析用途で活用されます。

Indexed Runtime Field

Indexed Runtime Fieldは、スクリプトによる計算結果をインデックス時(データ投入時)に生成・保存するフィールドです。検索時にスクリプトを実行する必要がないため、Runtime Fieldよりも高速に検索・集計を実行できます。一方で、計算結果をインデックスに保存するためストレージを消費し、定義済みのスクリプトは後から変更できません。検索性能を重視する場合に利用されます。計算結果は “_source”には保持されず、検索時は”fields”で指定する必要があります。

Indexed Runtime Fieldの定義例

PUT my-index-000001/
{
  "mappings": {
    "properties": {
      "timestamp": {
        "type": "date"
      },
      "temperature": {
        "type": "long"
      },
      "voltage": {
        "type": "double"
      },
      "node": {
        "type": "keyword"
      },
      "voltage_corrected": {
        "type": "double",
        "on_script_error": "fail",
        "script": {
          "source": """
        emit(doc['voltage'].value * params['multiplier'])
        """,
          "params": {
            "multiplier": 4
          }
        }
      }
    }
  }
}

Elastic Docs > Manage data > The Elasticsearch data store > Mapping > Runtime fields > Index a runtime field

https://www.elastic.co/docs/manage-data/data-store/mapping/index-runtime-field

Script Field

Script Fieldは、検索結果に対して追加情報を表示するためのフィールドです。検索時にスクリプトを実行して値を生成しますが、あくまで結果表示専用であり、クエリ・集計・ソートの対象にはできません。既存フィールドから派生した値を一時的に表示したい場合などに利用されます。

Script Fieldの使用例

GET my-index/_search
{
  "script_fields": {
    "tax": {
      "script": {
        "source": "doc['price'].value * 0.1"
      }
    }
  }
}

表 Script Field x Runtime Field x Indexed Runtime Field

項目Script FieldRuntime FieldIndexed Runtime Field
Script実行タイミング検索時検索時Index時
Mapping定義可能×
Queryで利用可能×
Aggregationで利用可能×
Sortで利用可能×
Indexに保存××
_sourceに保存×××
用途・特徴結果表示のみ動的計算動的計算・高速検索・結果保持

Runtime Fieldのエラーハンドリング

Runtime FieldやIndexed Runtime Fieldでは、スクリプト実行中にエラーが発生する可能性があります。例えば、存在しないフィールドへのアクセスや、数値変換に失敗した場合などです。このようなエラー発生時の動作は、on_script_error パラメータで制御できます。

Runtime Field
・on_script_error : fail : スクリプトエラー発生時に検索処理を失敗させる(デフォルト)
・on_script_error : continue : エラーが発生したドキュメントを無視し、検索処理を継続する

Indexed Runtime Field
・on_script_error : fail : スクリプトエラー発生時にドキュメントのインデックス登録を失敗させる(default) ・on_script_error : ignore : 対象フィールドを _ignored に記録し、インデックス登録を継続する

6. Elastic社が提供する無料のHands-onやOn-Demand Trainingで理解を深めよう

本記事では、Runtime Fieldの基本的な仕組みから、Mappingへの定義方法、検索時のruntime_mappingsによる定義方法、代表的な活用パターン、さらに試験で問われやすいポイントについて解説しました。しかし、Runtime Fieldの理解を深めるためには、実際にスクリプトを記述し、検索やAggregationの結果を確認しながら学習することが重要です。

Elastic社では、ElasticsearchやElastic Cloudを実際に操作しながら学習できる無償のHands-on TrainingやOn-Demand Trainingを提供しています。これらのトレーニングでは、Runtime Fieldだけでなく、Mapping、Query DSL、Aggregation、Painless Scriptなど、Elastic Certified Engineer Examで重要となる機能について実践的に学習できます。

特にRuntime Fieldは、単に構文を暗記するだけでなく、「どのような値が生成されるのか」「Aggregationや検索でどのように利用できるのか」を実際に確認することが重要です。Hands-on環境でさまざまなRuntime Fieldを作成し、検索結果の変化を確認することで理解を深めることができます。

また、Kibana DiscoverからRuntime Fieldを追加する操作や、runtime_mappingsを利用した一時的な分析も実際に試しておくことで、試験本番で出題された場合にも迷わず対応できるようになります。ぜひHands-on TrainingやElastic Cloud環境を活用し、Runtime Fieldを実際に動かしながら理解を深めてください。

Elastic Cloud アカウント作成

https://cloud.elastic.co/registration

Elastic Training

https://www.elastic.co/training

Elastic Learning Portal

https://learn.elastic.co/pages/58/home-page

7. 試験で問われるポイントの確認

試験にポイントを絞り、合格する上で重要な点を下記します。

  • Runtime FieldをMappingとして定義できること。
  • Runtime Fieldをクエリ時に使用できること。
  • クエリ時のRuntime Fieldにて、条件分岐(if文、nullチェック、size()チェック)や四則演算を含む簡単なPainless Scriptを記述できること。
  • Date Fieldや数値フィールドを利用した簡単なPainless Scriptを記述できるようにしておくこと。

当コンテンツの「Runtime Fieldに関するその他のポイント」については、試験範囲外となるため、概要を理解しておく程度で問題ありません。