对已有数据重建 ES 字段索引
重建 ES 字段索引,对已有数据生效。
方案 1:添加 multi-field mapping(推荐)
步骤 1:更新 mapping
PUT your_index/_mapping
{
"properties": {
"sendTime": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
步骤 2:重建索引使 mapping 生效
POST your_index/_update_by_query?refresh=true
{
"query": {
"match_all": {}
}
}
方案 2:零停机时间的安全做法
步骤 1:创建新索引模板
PUT _index_template/your_template
{
"index_patterns": ["your_index_pattern*"],
"template": {
"mappings": {
"properties": {
"sendTime": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
步骤 2:滚动更新(如果使用日期索引)
新的数据会自动应用新 mapping,旧数据保持不变。
验证方法
更新后验证是否生效:
GET your_index/_mapping/field/sendTime
应该看到:
{
"your_index": {
"mappings": {
"sendTime": {
"full_name": "sendTime",
"mapping": {
"sendTime": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}
在 Java 代码中使用
// 更新mapping后,可以这样排序
SortBuilder sortBuilder;
try {
sortBuilder = SortBuilders.fieldSort("sendTime.keyword").order(SortOrder.DESC);
} catch (Exception e) {
// 兜底方案
sortBuilder = SortBuilders.fieldSort("_id").order(SortOrder.ASC);
log.warn("sendTime.keyword字段不可用,使用_id排序");
}
注意事项
- 已有数据:需要
_update_by_query才能生效 - 性能影响:重建过程中可能影响查询性能
- 存储增加:keyword 字段会额外占用存储空间
- 建议时机:在业务低峰期执行
最安全的方案:先在测试环境验证,确认无问题后再在生产环境执行。
相关文章