Elasticsearch 中 match 查询和 term 查询有什么区别?
简化版
match 是全文查询,会先对查询文本做 analyzer 分析,再用 token 去倒排索引里查;term 是精确词项查询,不分析输入,直接拿给定值匹配倒排里的 term。text 字段常用 match,keyword 字段常用 term。
详细版
如果 title 是 text 字段,索引时 "Quick Fox" 可能被分成 quick 和 fox。这时:
{ "match": { "title": "Quick Fox" } }
会把查询也分析成 token 再查。而:
{ "term": { "title": "Quick Fox" } }
通常查不到,因为倒排里可能没有完整的 Quick Fox 这个 term。面试回答要抓住:match 面向全文检索,term 面向精确匹配;是否分析输入是核心区别。
完整版教学
一、match 和 term 的根本差别是是否分析查询文本
Elasticsearch 的倒排索引存的是 term,不一定是原文。match 查询会走字段的搜索 analyzer,把用户输入拆成 token;term 查询不会分析输入,它认为你已经给出了精确 term。
match: "Quick Fox" -> analyzer -> ["quick", "fox"] -> search
term : "Quick Fox" -> no analyzer -> search exact term "Quick Fox"
记忆钩子:match 先分词再查,term 拿原值直接查。
二、text 字段为什么常用 match
text 字段用于全文检索,索引时会被 analyzer 处理。
假设字段值是:
{ "title": "The Quick Fox" }
standard analyzer 可能产生:
["the", "quick", "fox"]
查询 Quick Fox 时,如果用 match,查询侧也会被分析成 quick、fox,因此能命中。如果用 term 查 "Quick Fox",倒排里没有这个完整 term,就很可能查不到。
这就是很多新手“明明有数据却 term 查不到”的原因。
三、keyword 字段为什么常用 term
keyword 字段通常不分词,整个值作为一个 term,适合 ID、状态、标签、邮箱、枚举、精确过滤。
{
"status": "PAID",
"email": "alice@example.com"
}
对应查询:
{
"term": {
"status": "PAID"
}
}
如果字段有 .keyword 子字段,也常用:
{ "term": { "title.keyword": "The Quick Fox" } }
这表示按完整标题精确匹配,而不是全文召回。
四、大小写和 normalizer 是常见坑
term 不分析输入,所以大小写必须和索引 term 一致。status 存成 Paid,你用 PAID 查可能查不到。
keyword 字段如果想做大小写归一,可以配置 normalizer。
{
"settings": {
"analysis": {
"normalizer": {
"lowercase_norm": {
"type": "custom",
"filter": ["lowercase"]
}
}
}
}
}
normalizer 可以理解为 keyword 字段上的轻量分析,通常不切词,只做规范化。
五、match 不是只能查 text,term 也不是只能查 keyword
这是面试里容易被追问的细节。技术上 match 可以用于 keyword 字段,term 也可以用于 text 字段,但语义和效果要看字段最终索引的 term。
| 字段类型 | 常用查询 | 原因 |
|---|---|---|
text | match | 查询文本需要分析 |
keyword | term | 精确值不需要切词 |
| 数字/日期 | term/range | 结构化条件 |
text.keyword | term | 完整字符串精确匹配 |
所以正确说法不是“禁止混用”,而是“按字段的索引方式选择查询”。
六、怎么排查 match/term 查询异常
排查步骤可以很固定:
1. 看 mapping:字段是 text 还是 keyword
2. 用 _analyze:确认 text 字段索引和搜索 token
3. 看 DSL:match/term 是否符合字段语义
4. 看大小写:keyword 是否需要 normalizer
5. 看 .keyword:是否应该查多字段
如果用户投诉精确标题查不到,可能应该查 title.keyword。如果用户投诉关键词搜不到,可能 analyzer 或同义词词典有问题。
七、常见误区与追问
- 误区:term 查询更快,所以全文搜索也都用 term。 term 不分析输入,用在 text 字段上经常查不到预期结果。
- 误区:match 查询就是模糊查询。 match 是全文查询,会分析文本,不等于 wildcard 或 fuzzy。
- 误区:keyword 字段不能用 match。 可以用,但通常没有必要,精确匹配更常用 term。
- 追问:为什么
term查text字段查不到? text 字段索引的是分词后的 term,不一定有原始完整字符串。 - 追问:
.keyword子字段有什么用? 同一文本既可全文搜索,也可完整值过滤、排序和聚合。 - 追问:大小写不一致怎么处理? text 可通过 analyzer,keyword 可配置 normalizer 或写入前统一。
八、加强记忆
match 和 term 记成“全文先分析,精确直接查”。text 字段索引时会被分词,所以查询侧通常用 match;keyword 字段保留整体值,过滤、排序、聚合常用 term。遇到查不到,先看 mapping 和 _analyze,再判断是不是应该查 .keyword,别把 DSL 当成脱离字段类型的孤立语法。