在没有kibana的ES(elasticsearch)线上生产环境集群中,如何通过命令行修改或增加字段而不需要reindex?
背景
线上生产环境一般都是有专门的网络环境,当然一般都不是暴露到公网的,也跟开发/测试环境网络是隔离的,不可能说让你本地电脑直接用一个客户端就可以连接到线上生产环境进行各种修改操作,一般都会有抓门的tl流程。
查看索引模版最新的版本
查看最新索引版本:
bash
curl -X POST "http://192.168.200.22:9200/_alias/index_template_name" \
-u elastic:password \
-d '{"size":1,"sort": [{"@timestamp": {"order": "desc"}}]}'
或者查看所有版本记录:
bash
curl -X POST "http://192.168.200.22:9200/_alias/index_template_name" \
-u elastic:password
修改或增加新的字段,需要保证原来的数据不受影响,例如从 -000006 提取的 mapping 中引用了自定义分析器(如 url_analyzer、ngram_analyzer 等),但在创建新模板时没有同时提供这些分析器的定义。这些分析器通常定义在索引的 settings 中。
你需要将 -000006 的 settings (特别是 analysis 部分)一并复制到新模板中。以下是完整的步骤:
✅ 完整步骤
1️⃣ 提取 -000006 的完整 settings 和 mappings
bash
# 获取 settings(包含分析器定义)
curl -s -u elastic:password "http://192.168.200.22:9200/index_template_name-000006/_settings" | jq '.["index_template_name-000006"].settings' > settings.json
# 获取 mappings
curl -s -u elastic:password "http://192.168.200.22:9200/index_template_name-000006/_mapping" | jq '.["index_template_name-000006"].mappings' > mappings.json
或者通过如下创建 settings :
仅提取分析器配置
bash
curl -s -u elastic:password "http://192.168.200.22:9200/index_template_name-000006/_settings" \
| jq '.["index_template_name-000006"].settings.index.analysis' > analysis.json
创建干净的 settings 文件
bash
echo '{"analysis": '$(cat analysis.json)'}' > settings.json
如果 analysis.json 内容为空(无自定义分析器),则设置 {}。
2️⃣ 修改 mappings.json 修改或者添加新增字段 task_detail_id
用编辑器打开 mappings.json,在 properties 对象末尾添加:
json
"task_detail_id": { "type": "long" }
注意保留前一个字段末尾的逗号。
3️⃣ 创建新的索引模板(包含 settings 和 mappings)
bash
curl -X PUT "http://192.168.200.22:9200/_index_template/index_template_name_v2" \
-u elastic:password \
-H 'Content-Type: application/json' \
-d "{
\"index_patterns\": [\"index_template_name-*\"],
\"priority\": 210,
\"template\": {
\"settings\": $(cat settings.json),
\"mappings\": $(cat mappings.json)
}
}"
bash
curl -X PUT "http://192.168.200.22:9200/_index_template/index_template_name_v2" -u elastic:password -H 'Content-Type: application/json' -d "{
\"index_patterns\": [\"index_template_name-*\"],
\"priority\": 210,
\"template\": {
\"settings\": $(cat settings.json | jq '.index'),
\"mappings\": $(cat mappings.json)
}
}"
注意 :$(cat settings.json | jq '.index') 会提取 index 对象,因为 ES 模板的 settings 直接放在 template.settings 下,不需要再套一层 index。如果 settings.json 中已经包含 "index": { ... },则需要取 .index。
4️⃣ 验证模板创建成功
bash
curl -s -u elastic:password "http://192.168.200.22:9200/_index_template/index_template_name_v2" | jq '.index_templates[0].name'
5️⃣ 执行 rollover 生成新索引(例如 -000008)
bash
curl -X POST "http://192.168.200.22:9200/index_template_name/_rollover/" -u elastic:password
bash
curl -X POST "http://192.168.200.22:9200/index_template_name/_rollover/" -u elastic:password
6️⃣ 检查新索引的字段类型是否与 -000006 一致
bash
curl -s -u elastic:password "http://192.168.200.22:9200/index_template_name-000008/_mapping" | jq '.[].mappings.properties.source'
应该输出 "type": "keyword" 而不是 "type": "text"。
7️⃣ 测试查询
bash
curl -u elastic:password "http://192.168.200.22:9200/index_template_name/_search" -H 'Content-Type: application/json' -d '{
"query": {"bool": {"must": [{"term": {"project_id": 655}}, {"term": {"source": "rcct-crawler"}}]}},
"size": 1
}'
应该能返回数据。
🛠 如果仍然失败(备选方案)
如果上述方法由于权限或复杂依赖仍然失败,可以直接使用 _reindex 将 -000007 的数据重新索引到一个新索引,并在 reindex 时指定 mapping。
- 创建新索引
index_template_name-000008_fixed,并显式指定与-000006相同的 mapping(不依赖模板)。 - 使用
_reindex将-000007的数据迁移过去,并设置dest的index为该新索引。 - 将别名
index_template_name切换到新索引。
但这比修复模板要复杂,建议优先修复模板。
根据错误信息,问题在于你提取的 settings.json 包含了索引的只读元数据(如 index.uuid、index.creation_date、index.version.created 等),这些字段不允许在索引模板中显式设置。
你需要仅保留允许动态配置的设置 ,主要是 analysis 部分(自定义分析器定义)。以下是正确步骤:
📌 操作原因
- 直接复制整个
settings包含了 ES 内部元数据(如uuid、creation_date、version.created),这些是只读的,不能在模板中设置。 - 解决方案:只提取
analysis部分,这是唯一需要在新索引中保留的自定义配置。
按照上述步骤操作后,新索引将完全兼容 -000006 的 mapping,查询即可恢复正常。