暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

高基数字段别再用 text 了——keyword 类型的正确打开方式

项目实操阶段 request_id、user_agent、IP 地址、URL、UUID 这类字段,只要唯一值动辄成千上万甚至上百万,一律用 keyword,别用 text。

选错类型,轻则聚合查询慢,重则直接把 mapping 撑爆。

一、keyword 和 text,根子上就不是一回事

这两个类型经常被新手搞混,但底层逻辑完全不同。

text 类型:写入前要过分词器,一句话拆成好几个词,分别建倒排索引,专门为全文搜索设计的。你搜"分布式系统",能匹配到"分布式"或"系统"任意一个词命中的文档,靠的就是这套分词机制。

keyword 类型:不分词,原样存成一个完整的值,直接进词典(Term Dictionary)做精确匹配。你拿它做聚合(aggregation)、排序(sort)、过滤(filter),又快又准,因为词典里存的就是完整值,不用像 text 那样把分词结果拼回去比对。

一句话记住:要搜索用 text,要聚合排序用 keyword。

二、高基数字段为什么必须是 keyword

高基数(high-cardinality)字段,指的是唯一值特别多的字段。典型的比如 request_id(每条请求一个唯一 ID)、user_agent(浏览器标识五花八门)、IP 地址、UUID。

这类字段如果误用了 text,会出两个问题:

  1. mapping 爆炸
    ES 默认会给 text 字段自动生成对应的 keyword 子字段用于聚合,字段一多、唯一值一多,倒排索引和词典体积双双膨胀,内存和磁盘都跟着遭殃。
    Elasticsearch 8.X 防止 Mapping “爆炸”的三种方案
  2. 聚合变慢甚至跑不动
    text 字段做聚合,得先把分词结果还原、去重、再统计,高基数场景下这个过程会非常吃 CPU 和堆内存。

所以处理日志类数据时,遇到 request_id、user_agent 这种字段,思路很简单:它需不需要被全文搜索命中?不需要,那就老老实实用 keyword。

三、一份能直接抄的索引模板

下面这份模板,专门给日志场景用,覆盖了上面说的高基数字段:

PUT _index_template/logs_template
{
  "index_patterns": ["logs-*"],
  "template": {
    "settings": {
      "number_of_shards"3,
      "number_of_replicas"1
    },
    "mappings": {
      "properties": {
        "request_id": {
          "type""keyword"
        },
        "user_agent": {
          "type""keyword"
        },
        "@timestamp": {
          "type""date"
        },
        "message": {
          "type""text"
        }
      }
    }
  }
}

这份模板有几个细节值得说道说道:

  • index_patterns 用了通配符 logs-*

    意味着以后所有 logs-2026-07-26
     这种按天滚动的索引,都会自动套用这份模板,不用每天手动建索引。
    Elasticsearch ILM 索引生命周期管理常见坑及避坑指南
    视频 | Elasticsearch ILM索引生命周期管理
  • request_id / user_agent 用 keyword
    精确匹配、聚合、排序全都撑得住,不会因为唯一值太多拖垮性能。
  • message 保留 text
    日志正文这种需要全文检索的字段,该分词还是得分词,不能一刀切全用 keyword。
  • number_of_shards: 3,number_of_replicas: 1
    分片数和副本数是根据数据量和高可用需求配的,日志场景数据量通常较大,分片数不能设成 1,副本至少留一份保证节点故障时服务不中断。

四、上线前必须留意的几个坑

  1. keyword 不是万能药,别拿它做全文搜索
    你要是把 message 这种正文字段也设成 keyword,那这个字段就只能精确匹配整句话,用户体验直接崩掉。
  2. 测试要用真实基数,别拿几十条数据测
    线上跑到几百万唯一值和测试环境跑一万条,完全是两个世界,性能表现天差地别。
  3. 排序场景盯紧 fielddata 内存占用
    虽然 keyword 字段默认走 doc_values(磁盘友好),但一旦涉及某些排序场景启用 fielddata,高基数字段照样能把堆内存吃穿,这个指标得进监控大盘。
    Elasticsearch 内部数据结构深度解读
  4.权限和资源监控不能省
这类模板一旦上生产,尤其是涉及日志这种持续写入的场景,务必做好资源监控和访问控制,管理员权限操作要留痕,别图省事关掉审计。
如何监控 Elasticsearch 集群健康状态并实现邮件自动预警?

五、一句话总结

高基数字段的 mapping 选型,本质上是"搜索需求"和"聚合需求"的取舍。分清楚这个字段到底是用来搜的还是用来统计的,type 该填 keyword 还是 text 就一目了然了。

前文给出的这份模板可以直接拿去改一改字段名就上生产,但基数测试和资源监控这两步,一步都不能省。





文章转载自铭毅天下Elasticsearch,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论