--- title: "Easysearch:text 和 keyword 的区别,新手 90% 都理解错了" date: 2026-02-01 lastmod: 2026-02-01 description: "深度对比 Easysearch 中 text 和 keyword 字段类型的本质差异,揭示分词处理、查询方式、功能支持的区别,阐述新手3大高频误区,提供多字段配置方案实现全文搜索与精确匹配共存。" tags: ["text vs keyword", "字段类型", "常见误区"] summary: "一、字段类型核心差异(新手最易踩坑点) # 对比维度 text 字段 keyword 字段 分词处理 索引时通过分析器(如 IK、标准分词)拆分文本,支持中文 / 多语种分词 📝"Apple iPhone 15 Pro" → [“apple”, “iphone”, “15”, “pro”] 不分词,原样存储为完整字符串 🔒例:“Apple iPhone 15 Pro” → 仅保留原始值 索引结构 构建倒排索引,支持全文检索和相关性评分 存储原始值,支持精确匹配和聚合分析 查询方式 需用 match/match_phrase 查询(分词匹配) 需用 term/terms 查询(精确匹配) 功能支持 ❌ 不支持聚合(如分组统计)、排序 支持模糊匹配、拼写容错(fuzziness) ✅ 支持聚合、排序、过滤❌ 不支持分词匹配 大小写处理 默认转为小写(依分析器配置) 严格区分大小写(原样匹配) 关键原理:Easysearch 基于 Lucene 内核,text 字段为「全文检索优化」,keyword 为「精确查询优化」,字段类型直接决定查询逻辑与性能。" --- ### 一、字段类型核心差异(新手最易踩坑点) | 对比维度 | text 字段 | keyword 字段 | | -------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | | **分词处理** | 索引时通过分析器(如 IK、标准分词)拆分文本,支持中文 / 多语种分词 📝"Apple iPhone 15 Pro" → ["apple", "iphone", "15", "pro"] | 不分词,原样存储为完整字符串 🔒例:"Apple iPhone 15 Pro" → 仅保留原始值 | | **索引结构** | 构建倒排索引,支持全文检索和相关性评分 | 存储原始值,支持精确匹配和聚合分析 | | **查询方式** | 需用 `match`/`match_phrase` 查询(分词匹配) | 需用 `term`/`terms` 查询(精确匹配) | | **功能支持** | ❌ 不支持聚合(如分组统计)、排序 支持模糊匹配、拼写容错(`fuzziness`) | ✅ 支持聚合、排序、过滤❌ 不支持分词匹配 | | **大小写处理** | 默认转为小写(依分析器配置) | 严格区分大小写(原样匹配) | > 关键原理:Easysearch 基于 Lucene 内核,text 字段为「全文检索优化」,keyword 为「精确查询优化」,字段类型直接决定查询逻辑与性能。 ### 二、典型使用场景(新手快速选型指南) #### 1. text 字段:适合「全文搜索场景」 - **核心场景**:用户输入自然语言、需模糊匹配的内容 - 商品标题 / 描述(如电商搜索 “无线耳机” 匹配 “Bluetooth headphones”) - 文章正文、用户评论(需分词检索关键词) - 日志详情(需检索具体报错信息) - **实战示例**: ```json // 正确查询:text字段用match分词匹配 { "query": { "match": { "product_desc": "无线蓝牙耳机" } } } ``` - **Easysearch 优势**:支持本地优化的中文分词(IK 企业版、拼音 / 简繁体转换),比原生 Elasticsearch 更适配中文场景。 #### 2. keyword 字段:适合「精确匹配场景」 - **核心场景**:需严格匹配、排序或统计的结构化数据 - 状态码(如 "ERROR"/"SUCCESS")、IP 地址、邮箱 - 分类标签(如商品类目、文章标签) - 聚合分析(如统计各品牌商品数量) - **实战示例**: ```json // 正确查询:keyword字段用term精确匹配 { "query": { "term": { "brand.keyword": "Apple" } } } // 正确用法:聚合统计各状态日志数量 { "aggs": { "status_count": { "terms": { "field": "status.keyword" } } } } ``` - **关键提醒**:动态映射下,text 字段会自动生成 `.keyword` 子字段(如 `name.keyword`),可直接用于精确查询。 ### 三、新手 3 大高频误区(避坑指南) ❌ **误区 1**:对 text 字段用 `term` 查询(如用 `term: "Apple"` 查 text 类型的商品名) → 后果:因 text 已分词为小写,无法匹配原始字符串,返回空结果 ✅ 修正:用 `match` 查询,或改用 `.keyword` 子字段 ❌ **误区 2**:对 keyword 字段用 `match` 查询(如用 `match: "error"` 查日志状态) → 后果:多此一举且性能差(`match` 会先分词再匹配,而 keyword 未分词) ✅ 修正:直接用 `term: { "status.keyword": "ERROR" }` ❌ **误区 3**:用 text 字段做聚合 / 排序(如统计 text 类型的 “分类” 字段) → 后果:报错或结果混乱(text 未开启 fielddata 时不支持聚合) ✅ 修正:改用 keyword 字段或 `.keyword` 子字段 ### 四、特殊场景解决方案 若需同时支持「全文搜索 + 精确匹配」(如商品名既需模糊检索,又需精确排序),可使用 **多字段(multi-fields)** 配置: ```json { "mappings": { "properties": { "product_name": { "type": "text", // 全文搜索用 "fields": { "keyword": { // 精确匹配/聚合用 "type": "keyword", "ignore_above": 256 // 忽略超长字符串 } } } } } } ```