text 字段经过分词处理,适合全文检索但不支持聚合排序;keyword 字段不分词,适合精确匹配、聚合和排序。选错类型会导致查询结果为空或聚合报错。
先说结论:text 用于模糊搜索长文本,keyword 用于精确匹配短字符串,查询时必须匹配对应的查询语句。
- 适合:text 类型存储文章、日志详情,keyword 类型存储 ID、状态、邮箱。
- 重点看:text 字段默认使用 match 查询,keyword 字段默认使用 term 查询。
- 别忽略:keyword 类型默认 ignore_above 为 256,超过该长度的字符不会被索引。
命令速用版
PUT /my_index
{
"mappings": {
"properties": {
"content": { "type": "text" },
"status": { "type": "keyword" }
}
}
}
GET /my_index/_search
{
"query": { "match": { "content": "search text" } }
}
GET /my_index/_search
{
"query": { "term": { "status": "open" } }
}为什么会这样
根本原因在于索引时的数据处理方式不同。text 字段在写入时会经过分析器分词,将文本拆分成多个词条存入倒排索引;keyword 字段则保持原始值整体存储,通常加入 doc_values 以支持排序和聚合。
分步处理
第一步,确认数据用途。如果需要全文检索、模糊匹配,选择 text 类型;如果需要精确过滤、排序、聚合,选择 keyword 类型。
第二步,配置映射。创建索引时明确指定字段类型,text 类型可配置 analyzer,keyword 类型可配置 ignore_above。
第三步,选择查询语句。对 text 字段使用 match 查询,对 keyword 字段使用 term 查询。
怎么验证是否生效
使用 _analyze API 查看分词结果,或使用 term 查询测试精确匹配。如果 text 字段使用 term 查询无结果,说明分词导致匹配失败;如果 keyword 字段能查出完整值,说明未分词。
常见坑
在 text 字段上使用 term 查询往往查不到数据,因为存储的是分词后的词条而非原文。在 text 字段上进行聚合或排序操作会报错,因为默认不开启 doc_values。keyword 字段存储超过 256 字符的字符串时,超出部分默认不被索引,无法被检索。
常见问题
text 字段能做精确查询吗?
默认不支持,但可以通过添加 keyword 子字段实现。在 mapping 中为 text 字段配置 fields 属性,生成一个 keyword 类型的子字段用于精确查询。
keyword 字段长度有限制吗?
有限制,默认最大支持 32766 个 UTF-8 字符,但默认 ignore_above 为 256,超过 256 字符的值不会被索引。
为什么聚合报错?
因为聚合操作需要 doc_values 支持,而 text 类型默认不启用 doc_values,需将字段类型改为 keyword 或开启 doc_values。
参考来源
- Elasticsearch 核心知识点:keyword 与 text 字段的区别、选型及实战
- ES keyword 类型和 text 有什么区别
- Elasticsearch 中 text 与 keyword 的区别 - 哈喽哈喽 111111 - 博客园
- Elasticsearch(text 和 keyword) 区别分析
- Elasticsearch - 关键词搜索 (keyword) 与全文搜索 (text) 的区别_CSDN 博客