首页/数据/NoSQL 速查/text 与 keyword 字段类型选择
Elasticsearch89 条

text 与 keyword 字段类型选择

text 会分词并支持全文检索但默认不能用于排序聚合;keyword 保留整串、适合精确过滤、排序与聚合;字符串两种需求常一起用 multi-field 兼顾。

NoSQL 速查数据更新于 2026-10-13

字段类型怎么选

text 会分词、支持全文检索,但默认不能用于排序与聚合;keyword 保留整个字符串,适合精确过滤、排序与聚合。字符串字段经常同时需要两种能力,于是用 multi-field 在同一字段下挂一个 keyword 子字段兼顾。类型一旦在映射中确定就不能修改,选型要在建索引前想清楚。

基本信息

text分词索引,用于全文检索;排序聚合需开启 fielddata(耗内存)
keyword整串匹配、term 查询、排序与聚合;默认不分词
数值类型long / integer / short / byte / double / float / scaled_float
日期与布尔date(含多种 format)、boolean
特殊类型ip / geo_point / object / nested / dense_vector
multi-field同一字段挂多个子类型,如 city 与 city.raw

典型使用场景

  • 商品标题、文章正文用 text 支持分词检索
  • 状态、标签、用户 ID 用 keyword 做精确过滤与聚合
  • 需要在同一字段上既检索又聚合时用 multi-field
  • 时间字段用 date 并显式声明 format,避免被推断成 text
  • IP 与坐标用专用类型,普通字符串无法做范围与距离查询
  • 对象数组需要成组匹配时用 nested 而不是普通 object

multi-field 示例

multi-field 示例
{
  "properties": {
    "city": {
      "type": "text",
      "fields": {
        "raw": { "type": "keyword", "ignore_above": 256 }
      }
    },
    "status": { "type": "keyword" },
    "created_at": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss||epoch_millis" }
  }
}

类型能力对照

类型全文检索排序聚合典型字段
text支持(分词)默认不支持标题、正文、描述
keyword不支持分词支持状态、标签、ID
integer/long不适用支持数量、计数
date不适用支持时间戳、创建时间
ip不适用支持(含网段)客户端地址
nested需 nested 查询有限制订单明细、地址列表
对 text 字段直接做 terms 聚合会报 fielddata is disabled;应改用 city.raw 这类 keyword 子字段,或在查询期用运行时字段转换。
keyword 子字段通常设置 ignore_above(常见 256),超长值不会被索引也进不了聚合结果,长文本不适合当 keyword。
数字被存成字符串(或字符串数字存成数值)会导致范围查询与聚合语义错位,写入前用一致的类型;类型不符时可考虑写入管道转换。
scaled_float 用缩放因子把小数存成整数,适合金额类字段兼顾精度与存储;货币金额常用分或万分位整数存储。

类型选型决策顺序

  • 先明确字段用途:全文检索、精确过滤,还是排序聚合
  • 既要检索又要聚合的字符串用 multi-field:主字段 text 加 keyword 子字段
  • 只做精确匹配与聚合的字符串直接设 keyword,省掉分词开销
  • 数量与金额避免用字符串存储,范围查询与聚合都依赖数值类型
  • 时间字段显式声明 date 与 format,不要依赖自动映射推断
  • 数组对象需要成组条件匹配时用 nested,普通 object 会跨元素串位

不同字段的查询方式

不同字段的查询方式
GET /my-index/_search
{ "query": { "match": { "title": "蓝莓 果酱" } } }                       # text:先分词

GET /my-index/_search
{ "query": { "term": { "status": "paid" } } }                          # keyword:整串匹配

GET /my-index/_search
{ "size": 0, "aggs": { "by_city": { "terms": { "field": "city.raw" } } } }  # 聚合走 keyword 子字段
字段类型属于映射的一部分,只能新增不能修改;给未来可能要聚合的字段预留 keyword 子字段,成本远低于事后重建索引。
自动映射对字符串的处理通常是 text 加 keyword 子字段,所以默认还能聚合;但显式声明为 text 之后就不会再有子字段,行为差异要记清。
对象数组若声明成普通 object,索引时会被扁平化,条件可能分别命中不同元素;只有 nested 才能保证同一元素内的字段成组匹配。

常用类型速查

  • 短枚举值如状态、类型、渠道:keyword
  • 名称与地址等需要模糊搜索的文本:text 加 keyword 子字段
  • 数量、计数、库存:integer 或 long
  • 价格与金额:scaled_float,或按分存储的整型
  • 时间点:date 并显式声明 format
  • IP 地址:ip 类型,可做网段范围查询
把字符串当作数值类型字段的查询值通常无命中,类型一致性是排查「有数据却查不到」的第一检查项。

易错点

  • keyword 默认 ignore_above 上限之外的值不建索引,聚合结果缺数据却看不出报错
  • 把说明文本误设为 keyword 会撑大索引体积,同时全文检索完全失效
  • 已经建成 text 的字段无法改成 keyword,只能重建索引迁移,选型要一次到位
  • 对 text 字段直接聚合或排序会报 fielddata is disabled,需要改用 keyword 子字段
  • 数组对象用普通 object 会跨元素串位匹配,需要成组条件时必须用 nested

数据来源与参考

  • Elasticsearch Guide: Field data types
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌