在设计 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) #
当你拿到一个新字段时,请按此流程决策:
- 这是一段很长的文字(如文章正文)吗?
- 是 -> 选 Text。
- 否 -> 进入下一步。
- 我需要对它进行全文检索(搜中间的词)吗?
- 不需要(只搜完全匹配)-> 选 Keyword。
- 需要 -> 进入下一步。
- 我需要对它进行排序或聚合(统计)吗?
- 不需要 -> 选 Text。
- 需要 -> 选 Text + Keyword (Multi-fields)。
总结 #
- Keyword 是给机器看的,用于过滤和统计,快准狠。
- Text 是给人看的,用于模糊搜索,理解语义。
- Multi-fields 是万能钥匙,能同时满足搜索和统计需求。
- 利用 Easysearch 的 ZSTD 压缩 能力,你可以更大胆地使用 Multi-fields 而无需过分担心存储成本。





