📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

在设计 Easysearch 的索引 Mapping 时,开发者面临的第一个也是最高频的灵魂拷问就是:
“这个字段,我到底该设为 text 还是 keyword?”

选错了会有什么后果?

  • 选了 text:无法排序,无法聚合,或者聚合报错 Fielddata is disabled
  • 选了 keyword:搜“手机”搜不到“苹果手机”,大小写必须完全一致。

本文将深入剖析这两种类型的底层区别,并给出 Easysearch 环境下的最佳选型策略。


1. 一图看懂核心区别 #

特性Keyword (精确值)Text (全文本)
处理方式原样存储。不分词,不转换大小写。分词处理。经过 Analyzer 拆分成词项 (Token)。
典型场景状态码、ID、标签、邮箱、URL、品牌名。文章正文、商品描述、日志消息内容。
主要用途精确过滤 (term)、排序、聚合 (Aggs)。全文检索 (match)、模糊匹配。
底层结构倒排索引 + Doc Values (列式存储)。倒排索引 (Inverted Index)。
能否聚合✅ 非常快 (基于磁盘)。❌ 默认禁用 (需开启 Fielddata,极耗内存)。

2. 深入剖析:Keyword (精确与统计之王) #

Keyword 是结构化数据的首选。如果你拿到一个字符串,心里想的是:“我以后要用这个值来分组统计”或者“我要精确查找这个特定值”,那么请毫不犹豫选择 keyword

2.1 什么时候选 Keyword? #

  • 枚举值:Status ("Active", "Closed"), Gender ("M", "F").
  • 唯一标识:User ID, Order ID, UUID, IP 地址。
  • 短文本标签:Product Tag ("New Arrival"), Category.
  • 需要排序/聚合:按价格排序、按品牌分组统计销量。

2.2 陷阱提示 #

keyword大小写敏感的!

  • 数据存入 "Apple"
  • 搜索 term: "apple" -> 搜不到
  • 搜索 term: "Apple" -> 搜到了

解决方案:如果你需要“精确匹配但不区分大小写”,可以使用 normalizer 将 keyword 统一转为小写存储。


3. 深入剖析:Text (智能搜索的核心) #

Text 是非结构化数据的归宿。它存在的意义就是为了被“拆解”,以便让人通过搜索其中的一部分词语找到整个文档。

3.1 什么时候选 Text? #

  • 长文本:博客文章、新闻内容、备注信息。
  • 自然语言:用户评论、即时通讯消息。
  • 混合搜索:比如地址(“北京市朝阳区…”),你希望搜“朝阳”能命中。

3.2 陷阱提示 #

千万不要尝试在 text 字段上开启 fielddata: true 来强行做聚合。

  • 这会将庞大的倒排索引加载到 JVM 堆内存中。
  • 后果:极易引发 OOM (Out Of Memory),导致节点崩溃。

4. 最佳实践:成年人不做选择,我全都要 (Multi-fields) #

在实际业务中,我们经常遇到这种需求:

“标题字段 (title),我既想通过关键词搜到它,又想按标题字母顺序排序。”

这时候,多字段(Multi-fields) 是标准解决方案。我们在 Mapping 中定义一个主字段为 text,并在其下定义一个子字段为 keyword

4.1 Mapping 配置示例 #

# 1. 主字段:用于全文搜索 (match)
# 2. 子字段:名字叫 raw (也可以叫 keyword)
# 3. 超过 256 字符的被截断(不索引该子字段)
PUT /products
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "ik_max_word",
        "fields": {
          "raw": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      }
    }
  }
}

4.2 如何使用? #

  • 搜索时:用 title
"match": { "title": "华为手机" }
  • 排序/聚合时:用 title.raw
"sort": [ { "title.raw": "asc" } ]

5. Easysearch 独家优势:ZSTD 压缩让“全都要”更轻松 #

在传统的 Elasticsearch 中,使用 Multi-fields 策略最大的痛点是存储膨胀。同一个字符串被存了两份(一份分词,一份原样),索引大小会显著增加。

但在 INFINI Easysearch 中,这一顾虑被大大减轻:

  • ZSTD 压缩:Easysearch 支持 ZSTD 算法。
  • 收益:对于重复度高的 Keyword 数据,ZSTD 能够提供极高的压缩比。这意味着,你在 Easysearch 中使用 text + keyword 双字段策略的磁盘成本,可能比其他引擎只存单字段的成本还要低。

因此,在 Easysearch 中,我们强烈推荐对于不确定的短文本字段(如标题、姓名、文件名),默认采用 Text + Keyword 的组合方式。


6. 决策流程图 (Cheat Sheet) #

当你拿到一个新字段时,请按此流程决策:

  1. 这是一段很长的文字(如文章正文)吗?
  • 是 -> 选 Text
  • 否 -> 进入下一步。
  1. 我需要对它进行全文检索(搜中间的词)吗?
  • 不需要(只搜完全匹配)-> 选 Keyword
  • 需要 -> 进入下一步。
  1. 我需要对它进行排序或聚合(统计)吗?
  • 不需要 -> 选 Text
  • 需要 -> 选 Text + Keyword (Multi-fields)

总结 #

  • Keyword 是给机器看的,用于过滤和统计,快准狠。
  • Text 是给人看的,用于模糊搜索,理解语义。
  • Multi-fields 是万能钥匙,能同时满足搜索和统计需求。
  • 利用 Easysearch 的 ZSTD 压缩 能力,你可以更大胆地使用 Multi-fields 而无需过分担心存储成本。