在ElasticsearchEDIT上将字段类型从文本迁移到关键字:

C.R*_*lon 8 mapping elasticsearch

当我想使用此命令将字段类型从文本更改为关键字时:

PUT indexStat/_mapping/StatCateg
{
  "StatCateg":{
    "properties": {
      "nom_categorie": {
        "type":"keyword","index": true
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我有这样的信息:

{
  "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
}
Run Code Online (Sandbox Code Playgroud)

C.R*_*lon 15

最后我在文档中看到,无法更改字段的数据类型:

更新现有映射

除了记录之外,现有的类型和字段映射无法更新.更改映射意味着使已编制索引的文档无效.相反,您应该使用正确的映射创建一个新索引,并将数据重新索引到该索引中.

所以唯一的解决方案是:

  • 重新创建具有良好数据类型的新索引
  • 使用Reindex API重新索引数据

  • 这是使用索引别名的情况之一:针对别名进行编码,并且可以在不停机的情况下更改其指向的实际索引。如果您对实际索引进行编码,则要么被迫在应用程序代码中更改索引名称,要么被重新索引两次以获取原始索引名称。 (3认同)

Jos*_*ush 12

不支持更改现有索引的数据类型(映射)。为此,请使用正确的类型(映射)和reindex您的数据创建一个新索引。

关于这样做的Elastic博客文章,并建议使用最佳实践方法为您的索引设置别名。


如果您没有别名索引

这些是所需的步骤,下次会更轻松,无需停机

  1. 获取当前映射 StatCateg
  2. StatCateg_v1使用正确的映射创建新索引
  3. 重新索引从StatCategStatCateg_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()
Run Code Online (Sandbox Code Playgroud)

如果你这样做?有一个别名索引

这些是所需的步骤,没有停机时间

  1. 获取当前映射 StatCateg_v1
  2. StatCateg_v2使用正确的映射创建新索引
  3. 重新索引从StatCateg_v1StatCateg_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()
Run Code Online (Sandbox Code Playgroud)