multi_match 是什么
multi_match 把一个查询串同时作用到多个字段上,是 match 查询的多字段版本。它用 type 参数决定「多字段得分怎么合成」:默认 best_fields 取得分最高的单个字段排名,most_fields 把各字段得分累加,cross_fields 则把多个字段当成一张大表按词条匹配。
基本信息
| 适用版本 | Elasticsearch 7.x / 8.x |
|---|---|
| 默认类型 | best_fields |
| 可选类型 | most_fields / cross_fields / phrase / phrase_prefix / bool_prefix |
| 字段权重 | fields 里用 ^数字 提升权重,如 title^3 |
| 微调参数 | tie_breaker 0-1,让非最高分字段按比例参与 |
典型使用场景
- 标题加正文的全局搜索:title^3 让标题命中权重更高
- 多语言字段:title 与 title.en 属于同义内容,用 best_fields 取最高分即可
- 人名被拆开:first_name + last_name 用 cross_fields,保证所有词都能落到字段上
- 同一内容多分词方式:如商品名同时建了标准与拼音字段,用 most_fields 汇总打分
- 输入联想:bool_prefix 配合 search_as_you_type 字段,边输边出候选
示例
示例
GET /my-index/_search
{
"query": {
"multi_match": {
"query": "quick brown fox",
"fields": ["title^3", "body"],
"type": "best_fields",
"tie_breaker": 0.3 # 次优字段按 30% 分值参与,减少同分抖动
}
}
}
GET /my-index/_search
{
"query": {
"multi_match": {
"query": "john smith",
"fields": ["first_name", "last_name"],
"type": "cross_fields",
"operator": "and" # 所有词都要出现,才不会被单个词拉出噪声
}
}
}
GET /my-index/_search
{
"query": { "multi_match": { "query": "quick", "fields": ["title", "title.pinyin"], "type": "most_fields" } }
}type 打分对照
| type | 打分方式 | 适用场景 |
|---|---|---|
| best_fields | 取单字段最高分,tie_breaker 修正 | 同义字段,如 title 与 title.en |
| most_fields | 各字段得分累加 | 同一内容的不同分词或不同表示 |
| cross_fields | 按词跨字段匹配,词级取最大权重 | first_name + last_name 这类被拆开的字段 |
| phrase | 在每个字段内按短语顺序匹配 | 要求词序正确,如产品型号 |
| phrase_prefix | 短语匹配,最后一词按前缀扩展 | 搜索框即时提示 |
| bool_prefix | 按词拆开做前缀匹配 | 配合 search_as_you_type 字段做联想 |
fields 里的 ^ 是相对权重,不是绝对分值;调权重前先用 explain 看分值构成,否则容易把次要字段调成主导排序的字段。
cross_fields 要求各字段使用相同的分词器,并通常搭配 operator: and 使用:它按词把所有字段合成一份词频视图,若某字段是 keyword 而另一个是 text,匹配行为会变得难以预料。
tie_breaker 只在 best_fields(及 phrase 类)下生效:默认 0 时除最高分字段外全被忽略,这解释了为什么“另一个字段明明也命中了”却不影响排名。