深入学习 ElasticSearch 的搜索(二):match 查询
深入学习 ElasticSearch 的搜索(二):match 查询
match 是 ElasticSearch 全文检索中最常用的查询。
如果搜索对象是文章标题、正文、简介、评论这类自然语言文本,通常优先考虑 match。
它的核心特点是:
查询文本会先经过 analyzer 分析,再用分析后的 term 去倒排索引中检索。
所以 match 不是简单的字符串包含,也不是直接拿原始查询内容去字段里扫描。
一、match 查询的基本写法
最简单的写法如下:
POST article_search/_search
{
"query": {
"match": {
"content": "倒排索引"
}
}
}
含义是:
- 查询
article_search索引 - 在
content字段中做全文检索 - 查询内容是
倒排索引
如果 content 是 text 字段,ElasticSearch 会使用字段对应的 analyzer 分析查询文本。
二、match 查询的执行过程
假设字段内容是:
倒排索引把文档到词的关系反过来
查询:
倒排索引
大致流程是:
- 查询文本进入 analyzer
- analyzer 生成一个或多个 term
- ElasticSearch 根据这些 term 查倒排索引
- 合并命中文档
- 计算
_score - 返回结果
这也是为什么 analyzer 对搜索效果影响很大。
中文场景中,如果“倒排索引”被拆成了:
倒排 / 索引
和被拆成:
倒 / 排 / 索 / 引
搜索效果会完全不一样。
三、match 和 analyzer 的关系
可以用 _analyze 先看查询文本会被拆成什么。
POST article_search/_analyze
{
"field": "content",
"text": "倒排索引"
}
这个请求会使用 content 字段实际绑定的 analyzer。
排查搜索问题时,这一步很重要。
如果 _analyze 的结果和你预期不一致,后面的 match 查询也很难符合预期。
四、operator:控制多个 term 的关系
match 查询中,如果查询文本被分析成多个 term,默认通常是 OR 关系。
例如查询:
ElasticSearch 倒排索引
可能被分析成:
elasticsearch
倒排
索引
默认情况下,只要命中其中一部分 term,就可能出现在结果中。
如果希望所有 term 都必须命中,可以使用 operator。
POST article_search/_search
{
"query": {
"match": {
"content": {
"query": "ElasticSearch 倒排索引",
"operator": "and"
}
}
}
}
常见取值:
or:默认,命中任意 term 即可and:所有 term 都要命中
and 更严格,召回更少;or 更宽松,召回更多。
五、minimum_should_match:控制最低命中数量
如果不想像 and 那么严格,也不想像默认 or 那么宽松,可以使用 minimum_should_match。
POST article_search/_search
{
"query": {
"match": {
"content": {
"query": "ElasticSearch 倒排索引 查询",
"minimum_should_match": 2
}
}
}
}
含义是:
查询分析出来的 term 中,至少要命中 2 个。
也可以使用百分比:
POST article_search/_search
{
"query": {
"match": {
"content": {
"query": "ElasticSearch 倒排索引 查询",
"minimum_should_match": "70%"
}
}
}
}
它适合处理用户输入较长的关键词,避免只命中一个很弱的词就返回太多无关结果。
六、match 查询会计算评分
match 属于 query context,会参与相关性评分。
例如:
POST article_search/_search
{
"query": {
"match": {
"content": "ElasticSearch 搜索"
}
}
}
结果中的 _score 会受到多种因素影响:
- 查询 term 是否命中
- 命中了多少 term
- term 在字段中出现的频率
- term 在整个索引中是否稀有
- 字段长度
所以 match 的结果通常是按相关性排序,而不是简单按文档 ID 或时间排序。
七、boost:给这条查询加权
match 支持 boost。
它不是给字段永久加权,也不是给某条文档预先加权,而是:
让当前这条 query 子句在最终
_score里更重要或更不重要。
例如:
POST article_search/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"title": {
"query": "ElasticSearch",
"boost": 3
}
}
},
{
"match": {
"content": {
"query": "ElasticSearch",
"boost": 1
}
}
}
]
}
}
}
含义是:
- 标题命中更重要
- 正文命中也有价值,但权重低一些
这类写法在搜索排序里很常见。
八、analyzer:临时指定查询分析器
match 默认使用字段的 search_analyzer,如果没有配置 search_analyzer,通常使用字段的 analyzer。
也可以在查询时临时指定 analyzer:
POST article_search/_search
{
"query": {
"match": {
"content": {
"query": "ElasticSearch 搜索",
"analyzer": "standard"
}
}
}
}
这适合做调试或少量特殊查询。
但业务上不建议到处临时指定 analyzer,否则索引时和搜索时的分析逻辑会变得很难维护。
九、fuzziness:容忍拼写错误
match 支持 fuzziness,用于处理拼写错误或字符误输入。
例如用户把 elasticsearch 输入成了 elasticsearh:
POST article_search/_search
{
"query": {
"match": {
"content": {
"query": "elasticsearh",
"fuzziness": "AUTO"
}
}
}
}
fuzziness 本质上是编辑距离式的近似匹配。
它适合英文拼写容错、低频兜底召回,但不要把它当成“智能搜索”。尤其中文场景里,分词结果会强烈影响模糊匹配的效果,乱开可能导致召回过多、排序变差。
十、zero_terms_query:分析后没有 term 怎么办
如果查询文本经过 analyzer 后没有留下任何 term,可以用 zero_terms_query 控制行为。
POST article_search/_search
{
"query": {
"match": {
"content": {
"query": "the",
"zero_terms_query": "none"
}
}
}
}
常见取值:
none:默认,不匹配任何文档all:匹配全部文档
实际业务中通常保持默认更安全,避免用户输入无效关键词时返回全部数据。
十一、operator=and 不等于 match_phrase
这一点很容易混淆。
POST article_search/_search
{
"query": {
"match": {
"content": {
"query": "ElasticSearch 倒排索引",
"operator": "and"
}
}
}
}
operator: "and" 的意思是:
查询文本分析出的多个 term 都必须命中。
但它不要求这些 term 必须连续,也不要求顺序相邻。
如果要查连续短语,应该使用 match_phrase。
十二、match 查询适合什么字段
match 最适合:
text字段- 标题
- 正文
- 摘要
- 评论
- 用户输入的关键词搜索
不太适合:
- ID
- 状态
- 分类
- 是否启用
- 枚举值
这些结构化字段更适合用 term 或 terms。
十三、match 查询 keyword 字段会怎样
如果对 keyword 字段使用 match,并不是一定不能用,但它通常会退化成接近精确匹配的效果。
例如:
POST article_search/_search
{
"query": {
"match": {
"category": "elasticsearch"
}
}
}
因为 category 是 keyword,不会像正文那样分词,所以这个查询通常能命中 category 正好是 elasticsearch 的文档。
但是工程上更推荐写成:
POST article_search/_search
{
"query": {
"term": {
"category": "elasticsearch"
}
}
}
原因是语义更清楚:
match:全文检索term:精确词项匹配
十四、常见误区
1. match 不是模糊包含
match 不是 SQL 里的:
LIKE '%关键词%'
它依赖的是 analyzer 产生的 term。
如果某个词没有以合适的 term 进入倒排索引,match 也不一定能搜到。
2. match 不是精确匹配
查询:
{
"match": {
"content": "ElasticSearch 倒排索引"
}
}
不代表必须完整包含这句话。
它通常会分析成多个 term,再根据匹配情况计算相关性。
如果要查固定短语,更适合用 match_phrase。
3. 中文搜索效果主要看分词
中文搜索中,很多问题不是 match 写错了,而是 analyzer 不合适。
排查顺序建议是:
- 用
_analyze看字段分词结果 - 确认索引时和搜索时 analyzer 是否符合预期
- 再调整
match的参数
十五、一句话总结
match 是全文检索的主力查询。
它适合用户输入关键词后搜索标题、正文这类 text 字段。
记住一句话:
match 会先分析查询文本,再用分析后的 term 去倒排索引中查找,并根据相关性评分返回结果。
参考链接
-
Match query
https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-match-query -
Analysis
https://www.elastic.co/docs/manage-data/data-store/text-analysis

更多推荐




所有评论(0)