Elasticsearch 如何把字符串字段默认映射改为不分词(keyword)?
Elasticsearch 动态映射默认把字符串同时建成 text+keyword 双字段。想改默认行为需用索引模板(index template)自定义 dynamic mapping。本文给出模板配置与新版本 composable template 写法。
通过索引模板(Index Template)覆盖动态映射规则:给 string 类型自定义映射为 keyword(旧版叫 not_analyzed)。模板只对新创建的索引生效,存量索引需重建。
现代写法(ES 7.8+,composable template)
PUT _index_template/string_keyword_template
{
"index_patterns": ["myapp-*"],
"template": {
"mappings": {
"dynamic_templates": [
{
"strings_as_keywords": {
"match_mapping_type": "string",
"mapping": { "type": "keyword" }
}
}
]
}
}
}
之后新建的 myapp-* 索引中,字符串字段一律映射为 keyword(整值索引、可聚合、不分词)。
旧版(ES 6.x 及更早)写法
PUT _template/string_not_analyzed
{
"template": "myapp-*",
"mappings": {
"_default_": {
"dynamic_templates": [
{ "strings": {
"match_mapping_type": "string",
"mapping": { "type": "string", "index": "not_analyzed" }
} }
]
}
}
}
建议:text+keyword 双字段其实更实用
默认行为(text 用于全文检索 + .keyword 子字段用于精确匹配/聚合)覆盖了两种需求,磁盘代价通常可接受。改默认映射前先想清楚:这个字段真的不需要全文搜索吗?
常见问题(FAQ)
Q:模板对已有索引生效吗? 不生效。改映射必须重建索引(reindex)。
Q:只想改个别字段? 用显式 mapping 定义该字段,比 dynamic_templates 更精确。