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

时间:2017-03-21 11:01:50

标签: elasticsearch mapping

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

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
}

2 个答案:

答案 0 :(得分:10)

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

  

更新现有映射

     

除了记录之外,现有的类型和字段映射不能   得到更新。更改映射意味着已经失效   索引文件。相反,您应该使用。创建一个新索引   正确的映射并将数据重新索引到该索引中。

所以唯一的解决方案是:

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

答案 1 :(得分:2)

不支持更改现有索引的数据类型(映射)。为此,请使用正确的类型(映射)和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()