フィールドにマッピング競合が発生した場合、Elastic Common Schema標準(ECS標準)であれデータソース固有であれ、Dev Toolsを使用してデータを再インデックスする必要が生じます。これらの競合は、インジェスト後のダウンストリーム機能に悪影響を与え、不正確な結果を引き起こしたり、可視化、ダッシュボード、Securityアプリ、アグリゲーションなどの機能においてデータセット全体の使用を妨げたりする可能性があります。このブログ記事では、この再インデックス処理の手順を詳しく説明します。
このブログのコンテンツは、Elasticのバージョン9.2.8と8.19.14、Filestream Integrationのバージョン2.3.0と1.2.0を使用して開発および検証されました。
重要な注意点:環境によっては、一部の手順を個別に変更する必要がある場合があります。さらに、Filestream Integrationバージョン2.3.3以降、@package コンポーネントテンプレートから動的テンプレートが削除されたことに注意してください。
再インデックス処理を開始する前に、環境における現在のストレージ割り当て状況を考慮することが重要です。以下に概説する手順では、既存のバッキングインデックスのコピーを作成し、それを一時的にホットティアに配置します。
Elasticsearchのデータティア
- ホット:ホットティアはElasticsearchにおける時系列データの入り口であり、最新かつ頻繁に検索されるデータを保存します。ホットティアノードは高速な読み書きを必要とするため、より多くのリソースと高速ストレージ(SSD)が必要となります。このティアは必須であり、新しいデータストリームインデックスはここに自動的に割り当てられます。
- ウォーム:時系列データは、ホットティアにある最近インデックス化されたデータよりもクエリ頻度が低くなると、ウォームティアに移動できます。ウォームティアには通常、直近数週間のデータが格納されます。更新は引き続き可能ですが、頻度は低いと思われます。ウォームティアのノードは、一般的にホットティアのノードほど高速である必要はありません。レジリエンス性確保のため、ウォームティアのインデックスは1つ以上のレプリカを使用するように設定する必要があります。
- コールド:検索頻度の低いデータは、ウォーム層からコールド層に移動できます。コールドティアは検索は可能ですが、検索速度よりもストレージコストの削減を優先します。あるいは、コールドティアでは、検索可能なスナップショットの代わりにレプリカ付きの通常のインデックスを保存することで、ウォームティアと比較してディスク容量の要件を減らすことなく、古いデータに対してより安価なハードウェアを使用することができます。
- フローズン:クエリされる頻度が低い、またはクエリされなくなったデータは、その残りのライフサイクルにおいてコールドティアからフローズンティアに移動します。このティアでは、スナップショットリポジトリと部分的にマウントされたインデックスを使用してデータを格納・読み込み、ローカルストレージとコストを削減しながら検索を可能にします。フローズンティアでの検索は、Elasticsearchがスナップショットリポジトリから凍結されたデータを取得する必要があるため、一般的にコールドティアでの検索よりも遅くなります。専用のフローズンノードの使用をお勧めします。
前提条件:競合が発生しているフィールドを特定
どのフィールドがマッピングの競合があるかを判別するには、[Stack Management]->[Data Views]-> logs-*(logs-*データビューはlogs-接頭辞で存在するデータの最高階層)に移動します。競合が発生した場合は、その旨を示す黄色のボックスが表示されます。[競合を表示]をクリックするか、検索ボックスの横にある[フィールドタイプ]ボックスで[競合]を選択します。


黄色の[競合]ボタンをクリックすると、どのインデックスがどのマッピングタイプに関連付けられているかが表示されます。
この状況(フィールドがkeywordとlongの両方としてマッピングされる場合)は通常、関連するコンポーネントテンプレートのデータストリームで特定のマッピングタイプが定義される前にデータがインジェストされたことが原因で発生します。このような場合、Elasticsearchは動的テンプレートに基づいてマッピングを設定しようとします。

フィールドに適切なマッピングを決定し、そのフィールドがECSフィールドであるかどうかを確認するには、ECSフィールドの参考資料で確認する必要があります。問題のフィールドがECSフィールドでない場合は、その値を確認して正しいマッピングを決定する必要があります。

フィールド(この例ではlog.offset)がECSに文書化されていない場合、次のステップはフィールドの値を調査し、どの競合するマッピングタイプが最も多くのバッキングインデックスを持っているかを判断し、他のインデックスのコンポーネントテンプレートを調べることです。
通常、インデックスの数が最も多いマッピングタイプが正しいものですが、該当するフィールドの値を確認して検証することをお勧めします。マッピングタイプ(例:long)の有効性を確認するには、そのタイプに対してフィールドの値が適切であることも確認する必要があります。この検証は、Discoverで問題のフィールドを検索することで行うことができます。同じフィールドを含む他のデータストリームをレビューすることで、追加の確認が得られる場合もあります。
マッピングの問題があるフィールドの値を確認するには、先ほど述べた黄色の[競合]ボタンに戻り、[競合]ボタンをクリックし、いずれかのバッキングインデックスをハイライトして、Discoverセッションに貼り付けてください。Kibanaクエリ言語(KQL)のステートメントは、_index: フィールド区切り文字を含めて、次のスクリーンショットのようにしてください。


新しいバッキングインデックスカスタムコンポーネントテンプレートを準備する
データストリームのマッピングの競合に対処するには、まず関連する@packageコンポーネントテンプレートを調べます。これは、[Stack Management]->[インデックス管理]->[コンポーネントテンプレート]で確認できます。データストリームを検索し、対応する @package リンクを選択します。このテンプレートには、すぐに使用できるフィールドのマッピングが含まれており、マッピングの不一致は一般的ではありませんが、より適切なタイプが見落とされている可能性があります。
テンプレートを確認して、問題のフィールドに必要なフィールドネストとマッピングが含まれていることを確認してください。例えば、テンプレートに log.offset が keyword として間違って記載されている場合、これが問題の原因です。
重要: @package/managedテンプレートの変更は推奨されていないため、今後のすべてのデータに対してマッピングタイプ(例えばlog.offset用)を修正するには、@customコンポーネントテンプレートを使用または作成する必要があります。
@package/managed テンプレートを変更することはお勧めしません。統合をより新しいバージョンに更新すると、@packageテンプレートに加えた変更が上書きされるためです。そのため、@customテンプレートの使用をお勧めします。- データストリームでマッピングの競合が発生している場合、
@customコンポーネントテンプレートに不足しているフィールド(ECSおよび非ECS)のネスティングまたはマッピングを追加する必要があります。このテンプレートがまだ存在しない場合は作成し、フィールドに対して正しいマッピングタイプを指定してください。 - データビューに複数の競合がある場合は、データストリームに必要な不足マッピングをすべて同時に適用して、再インデックス処理が複数回ではなく1回で済むようにしてください。
@customコンポーネントテンプレートに適切なデータタイプのエントリがあることで、将来のデータインジェストが同じマッピングガイドラインに従うことが保証されます。
@customコンポーネントテンプレートを作成(または使用中であり、入力されていることを確認)するには、[インデックステンプレート]に移動し、該当するデータストリームの名前を入力し、データストリームで使用されている適切な @custom テンプレートをクリックします。テンプレートがまだ作成されていない場合は、黄色のボックスが表示され、UIからテンプレートを作成できます。


以下のスクリーンショットは、 Create component template を選択した後の次のページを示しています。最初のページではデフォルト設定のままにし、マッピング または Next をクリックして マッピング ページに進んでください。


新しいフィールドのマッピングを明示的に設定するか、マッピングの競合があるフィールドを更新する場合、インデックスライフサイクルポリシーで設定された構成によりデータストリームがロールオーバーする際に、競合が存在するフィールドにエントリが必要です。
以下は、ファイルストリームデータストリームの @customコンポーネントテンプレート内にある log.offsetフィールドのマッピングを設定します。@packageから適切なマッピングを使用して、このデータセットに必要なカスタムフィールドを追加したり、必要なフィールドを更新したりする手順を繰り返します。この例では、オフセットを Long に設定すると、フィールドタイプが Numeric になり、数値タイプが Long になります。[フィールドを追加]をクリックし、エリアの外側をクリックして続行してください。


すべての必要なフィールドが追加されたら、レビューに進み、準備ができたら[コンポーネントテンプレートを作成]を選択します。このステップ以降に取り込まれるすべての新しいデータでは、log.offsetがlongに設定されます。

新しいバッキングインデックス構造を作成する
新しいバッキングインデックスには、データストリームのコンポーネントテンプレートからの既存のマッピングと、ECS ecs@mappings コンポーネントテンプレートが必要です。ecs@mappings コンポーネントテンプレートは、データストリームのコンポーネントの後に適用され、前のコンポーネントテンプレートでキャプチャされなかった可能性のある追加のマッピングのキャッチオールとして機能します。
データストリームの @package マッピングを表示するブラウザタブに移動します。([Stack Management]->[インデックス管理]->[コンポーネントテンプレート] logs-filestream.generic@package ->[管理]->[編集]の順に進んでください。)そこにアクセスしたら、[Review]セクションをクリックし、次に[Request]をクリックし、最後に右側の[Copy]ボタンをクリックしてください。コンポーネントテンプレートのJSONコンテンツをコピーすることで、log.offsetフィールドマッピングを更新する際に、残りのフィールドマッピングと設定が保持されます。JSONは、新しく再インデックスされたバッキングインデックスの基盤構造を形成します。
重要:テンプレートのJSONがコピーされずに再インデックスの作業が続行された場合、 log.offset競合は解決されますが、現在のマッピングの整合性が維持されないため、統合で新たな競合が発生し、元の問題を解決するために二重の作業が発生します。

別のブラウザタブを開き、Dev Toolsに移動して、コピーした内容を貼り付けてください。さて、貼り付けられた内容を修正しましょう。
リクエストの修正
1. インデックス名:_component_template/logs-filestream.generic@packageを再インデックスするバッキングインデックスの名前に置き換え、-1を末尾に追加してください。例えば、PUT <backing index to reindex>-1を用います。
- 末尾に付加された
-1は再インデックスを意味し、インデックスの作成日を基準とするデフォルトのILMロールオーバー設定とは競合しません。
2. 設定:JSONペイロード全体から"template"(3行目)と最後の閉じ括弧を削除します。3行目は"settings": {で始まる必要があります。
- 設定セクションの内部コンテンツを
"index.codec": "best_compression"に置き換えます。この操作により、インデックス作成時にElasticの最適な圧縮方式が適用されます。 "index.lifecycle.name": "logs"を追加し、"index.lifecycle.rollover_alias": ""の行も追加してください。"index.lifecycle.name": "logs"エントリーでは、ログのILMポリシーを新しいバックイングインデックスに適用します。ログを使用しない場合は、ILMポリシー名を変更してください。"index.lifecycle.rollover_alias": ""は空白です。このバッキングインデックスはロールオーバーされないため、ホット後の次のILMフェーズへのILMロールオーバーエラーを避けるために設定が必要です。
3. 構造:リクエストには、SettingsセクションとMappingsセクションの両方を含める必要があります。"mappings": { 内部には、"dynamic_templates" と "properties" セクションがあり、ハードコーディングされたフィールドとそのマッピングが含まれています。
4. 動的テンプレートの変更:現在の動的テンプレートセクションには、次にecs@mappings 動的テンプレートが追加されたときに上書きされる可能性のあるフィールドのエントリが含まれており、冗長性と不要な行が発生します。
"dynamic_templates"のセクションのうち、2番目のセクション「"_embedded_ecs-data_stream_to_constant": {」を除いてすべて削除してください。- 上記で説明したのと同じプロセスを繰り返し、
@packageコンポーネントテンプレートの動的マッピングを収集しますが、今回はecs@mappingsコンポーネントテンプレートの動的マッピングを収集します。ecs@mappingsコンポーネントテンプレートのマッピングの全内容をUIからコピーし、作業中のDev Toolsのdynamic_templatesセクションに貼り付け、適切な場所で重複や不要な行を削除する方が簡単な場合があります。これらの動的テンプレート設定の内容は"_embedded_ecs-data_stream_to_constant": {の後に含めてください。dynamic_templatesセクションは、Dev Toolsの以下のサンプル内容とよく似ているはずです。
dynamic_templatesが全く含まれていない/削除されていない 場合 、他のフィールド(下のスクリーンショットを参照)textとkeywordには、セクションdynamic_templatesが残されている場合の適切なマッピングに対して、二重マッピングが存在します。残っているのは"mappings"の下の"properties"セクションでなければなりません。これにより、フィールドが二重にマッピングされることで(既にそのようにマッピングされていない場合)、Data viewに問題が生じ、追加のマッピング競合が発生します。



5. メタデータの削除: "_meta"とラベル付けされた最後のセクションと、存在する場合は"version"とラベル付けされたセクションを削除します。
6. 書式設定:残りのセクションを自動的にインデントし、正常な実行を妨げる不要な波括弧を調整または削除します。

7. マッピングの変更: "properties" セクションに移動し、"log" を見つけ、その後 "offset" がその下にネストされている場所を見つけます。型をkeywordからlongに変更し、 "ignore_above": 1024,とラベル付けされた行エントリ(カンマを含む)を削除します。先に作成した@customコンポーネントテンプレートに複数のエントリが追加されている場合は、それらをここに含めてください。
これで、Dev Toolsのコンソールビューは以下の例のようになっているはずです。
コンソールが例のようになったら(追加のカスタムフィールドや環境固有のカスタム値も含め)、新しいバッキングインデックスのシェルを作成するコマンドを実行し、発生したエラーを解決するために一時停止します。
再インデックスプロセスを開始する
新しいバッキングインデックスのシェルが正常に作成されたので、次のステップは再インデックスとマッピングの競合を解決することです。
重要: マッピングの競合があるバッキングインデックスが最新のインデックスで、現在の書き込みインデックス(例えば、バッキングインデックスの終わりの番号が-000001)である場合、データストリームをロールオーバーする必要があります。データストリームをロールオーバーする必要があるのは、ドキュメントが投入されている現在の書き込みインデックスがライブバッキングインデックスであり、修正できないためです。
正しいフィールドマッピングが、以前に作成された@customコンポーネントテンプレートを介して新しい書き込みインデックスに適用されたため、すべての新しいドキュメントはこの変更を反映します。
これは、以下の手順を実行することで実現します。
例:

再インデックス作成では、同じ命名規則内の既存のバッキングインデックスから新しいインデックスにデータをコピーし、通常は必要な変更を適用します。これらの変更には、コンポーネントテンプレートの更新や、データを処理するための新しい取り込みパイプラインを追加することが含まれる場合があります。
次に、誤ったマッピングを持つバッキングインデックスから、新しいバッキングインデックスへデータがコピーされます。元のバッキングインデックスは更新済みであるため、新しいドキュメントを追加することはできません。新しいバッキングインデックスは同じ命名規則に従います。これにより、データの可視性と整合性が保たれ、適切なILMポリシーが適用されますが、再インデックスされたことを示す-1サフィックスが含まれます。
必要に応じてインデックス名を調整し、次のコードをコンソールに貼り付けます。wait_for_completion=falseを含めることで、文書コピーの進捗を追跡でき、残りの再インデックス時間の推定に役立ちます。この設定がなければ、以下のGET _tasksコマンドを使用してステータスを追跡することはできず、GET <backing index name>-1/_countを使用して新しいバッキングインデックス内のドキュメント数のみを確認することができます。
重要:再インデックス処理中に問題が発生した場合は、reindexコマンドを再実行しないでください。再実行すると処理が再開され、-1で終わるインデックスに重複レコードが作成されます。再起動が必要な場合は、まず末尾に-1が付いたインデックスを削除し、次に新しいバックイングインデックスシェルを作成するために先行するPUTコマンドを実行してください。

実行時には、応答にタスクIDが含まれます。このIDを使用して、コマンドGET _tasks/<task ID>で再インデックスの進行状況を監視できます。
再インデックスの所要時間は、元のインデックス内のデータ量によって異なります。GETコマンドを実行する際に"completed": trueを探すことで完了を追跡でき、同様の出力が得られるはずです。
GET _tasks/<task ID>

ドキュメント数に対する再インデックス処理が完了したので、次のステップは新しいバッキングインデックスと特定のフィールドのマッピングが正しいことを確認することです。
例:
log.offsetのマッピングは以下の通りであることを確認できます。他のフィールドに単一のマッピングエントリのみ(textとkeywordの両方ではない)があることを確認するには、それらを先行するPUTコマンドの動的テンプレートセクションの一部ではなかったフィールドと比較します。

再インデックスするバッキングインデックスに多数のドキュメントが含まれる場合は、新しいバッキングインデックスへコピーされているドキュメントの状況を確認すると便利です。次の2つのDev Toolsコマンドでカウントを比較して確認できます。
GET .ds-logs-filestream.generic-default-2026.04.14-000001/_count
GET .ds-logs-filestream.generic-default-2026.04.14-000001-1/_count

カウントが一致し、正しいマッピングが存在することを確認した後、新しいバッキングインデックスを含むようにデータストリームを更新します。これにより、インデックス管理で孤立したバッキングインデックスが発生するのを防ぎ、ILMポリシーがバッキングインデックスに適用されない状況を回避できます。
- 成功した場合、返される内容はtrueであることを示すものでなければなりません。

次のコマンドを使用して新しいバックインデックスが追加されていることを確認し、ilm_policy が正しいことを確認してください。

次に、以下のコマンドを使用して、バッキングインデックスのILMステータスを確認します。
- このインデックスが「ホット」と表示されるのは正常です。これは、インデックスがごく最近作成されたためです(8行目または10行目を確認してください)。


以下の手順を実行して、このデータストリームのILMポリシーにおけるホットフェーズの後の適切な次のティアに、バッキングインデックスをホットティアから移行します。下のcurrent_stepのphase、action、nameの具体的な値は、上のスクリーンショットの11行目、13行目、15行目でそれぞれ参照できます。
next_step値は、インデックスが移行する次のILMフェーズまたはデータティアを示します。
例:

- 必須ではありませんが、安全対策として、
_ilm/explainコマンドを再度実行して、バッキングインデックスが次のフェーズに移行し、ホット状態ではなくなったことを確認できます。

以下の条件が満たされたら、マッピングの競合があった元のバッキングインデックスを安全に削除できます。
- 新しいバックインデックスが正常に作成されました。
- ドキュメントは新しいインデックスに移され、ドキュメント数も一致しています。
- マッピングが修正されました(データストリーム固有のものとECSの両方)。
- データストリームには新しいバッキングインデックスが組み込まれています。
- ILMポリシーが適用され、インデックスはホットフェーズから移行しました。
重要:または、元のインデックスを削除する前にData viewページを確認することもできます。logs-* を選択し、再インデックスされたバッキングインデックス(-1 で終わるもの)が long セクションに表示されていることを確認してください。元のバッキングインデックスはkeywordの下にまだ存在しているはずです。再インデックスされたバッキングインデックスがlongセクションにない場合は、前の手順に戻って確認し、必要な修正を行ってください。
例:

競合を解決したら、Data viewページに戻り、 logs-*を選択します。もし競合が log.offsetだけに関連している場合、競合は表示されなくなります。他の競合が存在した場合、元のバッキングインデックスは競合リストに表示されなくなり、代わりに新しいバッキングインデックスがlongセクションにリストされます。
Discoverでlog.offsetフィールドに適切なアイコンが表示されていることを確認することもできます。


このプロセスを続け、マッピングの競合があるすべてのバックインデックスに対して上記の手順を繰り返し、すべてが正常に解決されるまで実行してください。
参照資料:
結びに
このブログの手順に従うことで、マッピングの競合を解決し、すべての新しいデータが正しくマッピングされることを保証できます。これは、必要なコンポーネントテンプレートをデータソースにリンクすることで実現します。このワークフローは、直接的な問題を解決するだけでなく、データと要件が進化するにつれて、スキーマの変更を管理するための安全で繰り返し可能なプロセスを確立します。




