web-dev-qa-db-ja.com

Elasticsearchでフィールドタイプをテキストからキーワードに移行する

このコマンドでフィールドのタイプをテキストからキーワードに変更したい場合:

PUT indexStat/_mapping/StatCateg
{
  "StatCateg":{
    "properties": {
      "nom_categorie": {
        "type":"keyword","index": true
      }
    }
  }
}

私はこのメッセージを持っています:

{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "mapper [nom_categorie] of different type, current_type [text], merged_type [keyword]"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "mapper [nom_categorie] of different type, current_type [text], merged_type [keyword]"
  },
  "status": 400
}
10
C.Rouillon

最後に、ドキュメントでフィールドのデータ型を変更することはできないことを確認します。

既存のマッピングの更新

文書化されている場合を除き、既存のタイプとフィールドのマッピングは更新できません。マッピングを変更すると、すでにインデックスが作成されているドキュメントが無効になります。代わりに、正しいマッピングで新しいインデックスを作成し、データをそのインデックスに再インデックスする必要があります。

したがって、唯一の解決策は次のとおりです。

  • 適切なデータ型で新しいインデックスを再作成します
  • Reindex APIでデータのインデックスを再作成します
14
C.Rouillon

既存のインデックスのデータ型(マッピング)の変更はサポートされていません。そのためには、正しいタイプ(マッピング)とデータをreindexで新しいインデックスを作成します。

エラスティックblogpostこれを行うことについて、また、インデックスにエイリアスを付けるというベストプラクティスのアプローチを使用することをお勧めします。


もししないなら ????エイリアスされたインデックスを持っている

これらは必要な手順です。次回はダウンタイムがなく、より簡単になります

  1. StatCategの現在のマッピングを取得
  2. 正しいマッピングで新しいインデックスStatCateg_v1を作成します
  3. StatCategからStatCateg_v1に再インデックス
  4. 古いインデックスを削除StatCateg
  5. エイリアスStatCateg_v1-> StatCategを作成します(次回は、ダウンタイムなしでこれを行うのが簡単になります)

スニペットの例(Pythonの場合):

import requests

current_index_name = 'StatCateg'
new_index_name = 'StatCateg-v1'
base_url = 'https://...'
mapping_changes = {
    "nom_categorie": {"type": "keyword"}
}

# ------------------------------------------------
# Get current mapping
r = requests.get('{base_url}/{index_name}'.format(base_url=base_url, index_name=current_index_name))
r.raise_for_status()
content = r.json()
mappings = content[current_index_name]['mappings']
mappings['properties'].update(mapping_changes)

# ------------------------------------------------
# Create a new index with the correct mappings
r = requests.put('{base_url}/{index_name}'.format(base_url=base_url, index_name=new_index_name), json={
    'mappings': mappings
})
r.raise_for_status()

# ------------------------------------------------
# Reindex
r = requests.post('{base_url}/_reindex'.format(base_url=base_url), json={
    "source": {
        "index": current_index_name
    },
    "dest": {
        "index": new_index_name
    }
})
r.raise_for_status()

# ------------------------------------------------
# Delete the old index
r = requests.delete('{base_url}/{index_name}'.format(base_url=base_url, index_name=current_index_name))
r.raise_for_status()

# ------------------------------------------------
# Create an alias (so that on next time this will be easier to do without downtime)
r = requests.post('{base_url}/_aliases'.format(base_url=base_url), json={
    "actions": [
        {"add": {
            "alias": current_index_name,
            "index": new_index_name
        }}
    ]
})
r.raise_for_status()

あなたがする場合✅エイリアスされたインデックスがあります

これらは必要なステップであり、ダウンタイムはありません

  1. StatCateg_v1の現在のマッピングを取得
  2. 正しいマッピングで新しいインデックスStatCateg_v2を作成します
  3. StatCateg_v1からStatCateg_v2に再インデックス
  4. エイリアス(StatCateg_v1-> StatCateg)を(StatCateg_v2-> StatCateg)と入れ替えます
  5. 古いインデックスを削除StatCateg_v1

スニペットの例(Pythonの場合):

import requests

index_name = 'StatCateg'
current_index_name = 'StatCateg_v1'
next_index_name = 'StatCateg_v2'
base_url = 'https://...'
mapping_changes = {
    "nom_categorie": {"type": "keyword"}
}

# ------------------------------------------------
# Get current mapping
r = requests.get('{base_url}/{index_name}'.format(base_url=base_url, index_name=current_index_name))
r.raise_for_status()
content = r.json()
mappings = content[current_index_name]['mappings']
mappings['properties'].update(mapping_changes)

# ------------------------------------------------
# Create a new index with the correct mappings
r = requests.put('{base_url}/{index_name}'.format(base_url=base_url, index_name=next_index_name), json={
    'mappings': mappings
})
r.raise_for_status()

# ------------------------------------------------
# Reindex
r = requests.post('{base_url}/_reindex'.format(base_url=base_url), json={
    "source": {
        "index": current_index_name
    },
    "dest": {
        "index": next_index_name
    }
})
r.raise_for_status()

# ------------------------------------------------
# Replace old index alias with new  
r = requests.post('{base_url}/_aliases'.format(base_url=base_url), json={
    "actions": [
        {"remove": {
            "alias": index_name,
            "index": current_index_name
        }},
        {"add": {
            "alias": index_name,
            "index": next_index_name
        }}
    ]
})
r.raise_for_status()

# ------------------------------------------------
# Delete the old index
r = requests.delete('{base_url}/{index_name}'.format(base_url=base_url, index_name=current_index_name))
r.raise_for_status()
1
Jossef Harush