Elasticsearch 8.X はどのようにフィールド名のバッチ変更をエレガントに実装していますか?

1.オンラインの実践問題

esに書き込む前のデータ形式は以下の通り

{"json_lbm_01":"test01","json_lbm_02":"test02","tmp_lbm_01":"test03","tmp_lbm_02":"test04"}

要件: 枯渇を考慮していないキーフィールドが多いため、記述されたキーに json_ を空に置き換え、tmp をコアに置き換えることが含まれている場合、単純にパイプラインを使用することは可能ですか?最終的な効果は次のようになります。 :

{
  "lbm_01":"test01",
  "lbm_02":"test02",
  "core_lbm_01":"test03",
  "core_lbm_02":"test04"
}

——問題の原因: Dead Elasticsearch Knowledge Planet https://t.zsxq.com/0bzWL3w1X

2. 認知的前提

Elasticsearch マッピングが作成されると、変更することはできません! マッピングの更新を可能にする特別なポイントがいくつかあります。以下を参照してください: Elasticsearch はマッピングを変更できますか? 変更方法は?

マッピング レベルに加えて、特にフィールド レベルを変更する場合は、考え方を変える必要があります。

3. ビジネス ニーズに合わせてマッピング フィールドを変更する必要がある場合はどうすればよいですか?

冒頭の質問を見ると、本質的にはモデリングの問題であり、モデリングの段階でうまく処理する必要があり、後の段階ではこの問題は存在しないという点については、全員が合意に達することを願っています。

Elasticsearch データ モデリングの重要性について、推奨される参考資料:

乾物 | Elasticsearch データ モデリング ガイド

最初の質問に対する次の解決策を検討してください。

3.1 解決策 1、フィールド エイリアスの実装。

フィールド エイリアス field-alias は、インデックス エイリアス エイリアスとは異なります。

誰もがインデックス エイリアスに精通しており、フィールド エイリアスはよく耳にしますが、実際に使用されることはあまりありません。

フィールド エイリアスは、Elasticsearch 6.4 の新機能です。以下を参照してください。

https://www.elastic.co/cn/blog/introducing-field-aliases-in-elasticsearch

通常、初期のモデリングで十分な宿題が行われるため、後のリンクは必要ありません。

  • 利点: 既存のマッピングは変更されませんが、更新操作はそれに基づいて実行されます。

  • 短所: バッチ内の 1,000 フィールドは、1,000 フィールドのマッピングを作成する必要があり、実際にはスクリプトで実装できます。

実用的な参照:

POST mytxindex-20230303/_bulk
{"index":{"_id":1}}
{"json_lbm_01":"test01","json_lbm_02":"test02","tmp_lbm_01":"test03","tmp_lbm_02":"test04"}


PUT mytxindex-20230303/_mapping
{
    "properties": {
      "lbm_01": {
        "type": "alias",
        "path": "json_lbm_01"
      },
      "lbm_02": {
        "type": "alias",
        "path": "json_lbm_02"
      },
      "core_lbm_01": {
        "type": "alias",
        "path": "tmp_lbm_01"
      },
      "core_lbm_02": {
        "type": "alias",
        "path": "tmp_lbm_02"
      }
    }
}

POST mytxindex-20230303/_search
{
  "query": {
    "match": {
      "lbm_01": "test01"
    }
  }
}

リコール結果データを以下のスクリーンショットに示します。

a45c2ee551389d29e1ddd​​16e5d3a575a.png

3.2 オプション 2、改造してから、再インデックス操作を実装します。

コアポイントは次のように紹介されています。

  1. 最初にテンプレート テンプレートを使用することをお勧めします。これにより、テンプレートが類似のフィールド名と一致する問題が解決されます。 

  2. 前処理パイプラインは、次の 2 つの部分で実装されます。

  • まず、スクリプトは古いフィールドと新しいフィールドの割り当てを認識します。

  • 次に、remove は不要な古いフィールドを削除します。 

利点: この操作は比較的一般的で、非常に満足のいくものです。

短所: インデックス データを移行し、移行中に前処理を行うには、再インデックスが必要です。

具体的な実装は次のとおりです。

#### step1:创建模板,有了模板,字段一键搞定
PUT _index_template/mytx_template_20230303
{
  "index_patterns": [
    "mytx_new_*"
  ],
  "template": {
    "settings": {
      "number_of_shards": 1
    },
    "mappings": {
      "dynamic_templates": [
        {
          "lbm_to_keyword": {
            "match_mapping_type": "string",
            "match": "lbm_*",
            "mapping": {
              "type": "keyword"
            }
          }
        },
        {
          "core_lbm_to_keyword": {
            "match_mapping_type": "string",
            "match": "core_lbm_*",
            "mapping": {
              "type": "keyword"
            }
          }
        }
      ]
    }
  }
}

#### step2:创建预处理管道
PUT _ingest/pipeline/mytx_pipeline_20230303
{
  "processors": [
    {
      "script": {
        "source": """
        ctx.lbm_01 = ctx.json_lbm_01;
        ctx.lbm_02 = ctx.json_lbm_02;
        ctx.core_lbm_01 = ctx.tmp_lbm_01;
        ctx.core_lbm_02 = ctx.tmp_lbm_02;
        """,
        "lang": "painless"
      }
    },
    {
      "remove": {
        "field": [
          "json_lbm_01",
          "json_lbm_02",
          "tmp_lbm_01",
          "tmp_lbm_02"
        ],
        "if": "ctx.json_lbm_01 != null && ctx.json_lbm_02 != null && ctx.tmp_lbm_01 != null && ctx.tmp_lbm_02 != null"
      }
    }
  ]
}

#### step3:数据迁移操作
POST _reindex
{
  "source": {
    "index": "mytxindex-20230303"
  },
  "dest": {
    "index": "mytx_new_001",
    "pipeline": "mytx_pipeline_20230303"
  }
}

#### step4:执行检索
POST mytx_new_001/_search

リコールの結果は次の図のとおりです。

94ad56acdca9cad54943ddaf45ea1ea9.png

3.3 解決策 3: トラバーサル問題の究極の解決策

スキーム 1 もスキーム 2 も、N フィールドの問題を解決できません。

複数のフィールドがあると仮定して、フィールドを 1 つずつコピーしたくないし、処理に shell や python などのサードパーティ スクリプトを使用したくありません。

それで、より良い解決策はありますか?ソリューション 3 はフィールド トラバーサルに基づいて実装され、フィールドはキーと値の組み合わせにすぎません。

最初に entry.getKey( ) でキーを取得し、キーに基づいて論理的な判断を行い、新しいキーを作成してから、古い値を新しいキーにコピーします。

最後に、putAll 経由で更新します。

PUT _ingest/pipeline/rename_fields_pipeline
{
  "processors": [
    {
      "script": {
        "source": """
          def new_fields = [:];
          for (entry in ctx.entrySet()) {
            String key = entry.getKey();
            if (key.startsWith('json_')) {
              key = key.replace('json_', '');
            } else if (key.startsWith('tmp_')) {
              key = 'core_' + key.replace('tmp_', '');
            }
            new_fields[key] = entry.getValue();
          }
          ctx.clear();
          ctx.putAll(new_fields);
        """
      }
    }
  ]
}


POST _reindex
{
  "source": {
    "index": "mytxindex-20230303"
  },
  "dest": {
    "index": "mytx_new_002",
    "pipeline": "rename_fields_pipeline"
  }
}

最終的な実行結果は次のとおりで、期待どおりです。

af3fe620503eb38723e65140c7914eea.png

4. まとめ

同様の問題に対して 3 つの異なる実装スキームが与えられたとしても、それらは与えられたビジネス要件を満たすことができます。

ただし、ビジネスの中期および後期段階で対処することはまだお勧めできません。より良い解決策として、Elasticsearchモデリング ステージを使用して、前述の中期および後期ステージの問題と同様に大量のデータ移行を伴う大きな変更を回避する計画を立てることをお勧めします。

より実用的なアイデアをぜひ共有してください。! !

推奨読書

  1. 全ネットワーク初公開!0 から 1 まで Elasticsearch 8.X クリアランス ビデオ

  2. Heavyweight | Dead Elasticsearch 8.X Methodology Cognition List (2022 National Day Update)

  3. Elasticsearchを体系的に学ぶには?

  4. 2023年、何とかして

bbf4e39ceb5ed93800ef3ebd2a02ef63.jpeg

より短い時間でより速く、より多くの乾物を手に入れましょう!

世界中の約 1900 人以上の Elastic 愛好家と一緒に改善しましょう!

a9817433353a35254b558ae1f9109236.gif

ワンランク上の乾物を学ぼう!

おすすめ

転載: blog.csdn.net/wojiushiwo987/article/details/129357709