全文搜索

22 May 2026 – wusfe · 4 min read

全文搜索:match、match_phrase、query_string 什么时候用哪个

用户在搜索框输入 "iPhone 15 Pro Max",你的 ES 应该怎么查?

你会想:不就是个 match 吗。但如果用户输的是 "iPhone 15 -mini"(排除 mini)、"title:iPhone AND price:[5000 TO 10000]"(高级语法)、或者 "iphne 15"(拼写错误)呢?

ES 提供了多种全文搜索方式,每一种都有自己最适合的场景。选错了,用户搜不到想要的东西;选得太重,集群压力上来。本篇逐一拆解。

Match:最通用的全文搜索

match 是 90% 场景下你该用的查询。它把搜索词用分词器拆开,然后去倒排索引里匹配。

GET /products/_search
{
  "query": {
    "match": {
      "title": "iPhone 15 Pro Max"
    }
  }
}

输入 "iPhone 15 Pro Max" 经标准分词器处理后变成 ["iphone", "15", "pro", "max"],然后 ES 去搜包含这些 term 的文档。默认是 OR 逻辑——文档包含任意一个 term 就算命中。

改为 AND 逻辑

{
  "match": {
    "title": {
      "query": "iPhone 15 Pro Max",
      "operator": "and"
    }
  }
}

现在文档必须包含全部四个 term。结果更精准但更少。

更灵活:minimum_should_match

{
  "match": {
    "title": {
      "query": "iPhone 15 Pro Max",
      "minimum_should_match": "75%"
    }
  }
}

4 个 term 中至少匹配 3 个(75%)。比 AND 宽松,比 OR 精准。

Match Phrase:短语精确匹配

用户搜 "iPhone 15",你不想返回"iPhone 壳适用于 15 寸笔记本"——term 顺序和位置必须一致。

GET /products/_search
{
  "query": {
    "match_phrase": {
      "title": "iPhone 15"
    }
  }
}

match_phrase 要求所有 term 按原顺序出现,且位置连续(slop 默认为 0)。

Slop:允许间隔

{
  "match_phrase": {
    "title": {
      "query": "iPhone 15",
      "slop": 2
    }
  }
}

slop: 2 允许 term 之间最多间隔 2 个位置。"iPhone 白色 15" 可以命中,"iPhone 全面屏 旗舰 15" 不行(间隔了 3 个)。

适用场景:搜标题、搜公司名、搜专有名词。

Multi Match:一次搜多个字段

用户输入一个关键词,你希望同时搜标题、描述、品牌:

GET /products/_search
{
  "query": {
    "multi_match": {
      "query": "iPhone 15",
      "fields": ["title^3", "brand^2", "description"]
    }
  }
}
  • title^3:标题匹配权重 3 倍——商品标题里包含关键字的排前面
  • brand^2:品牌匹配权重 2 倍
  • description:描述匹配权重 1 倍(默认)

Multi Match 的六种匹配模式

{
  "multi_match": {
    "query": "iPhone 15",
    "fields": ["title^3", "description"],
    "type": "best_fields"  // 默认:以最高分的字段为准
  }
}
type 行为 适用
best_fields 取匹配分最高的单个字段的分数 关键词搜索,最常用
most_fields 所有匹配字段的分数加起来 同义词/不同分词覆盖
cross_fields 把多个字段当作一个大字段处理 姓名搜索、地址搜索
phrase 在每个字段上跑 match_phrase 精确短语搜索
phrase_prefix phrase + 最后一个 term 做前缀匹配 搜索提示
bool_prefix 最后一个 term 做前缀,其余做 bool 即搜即现

最常用的三个:best_fields(默认)、cross_fields(多字段融合)、phrase_prefix(自动补全)。

Query String:给高级用户的搜索引擎语法

GET /products/_search
{
  "query": {
    "query_string": {
      "query": "title:iPhone AND price:[5000 TO 10000] -status:deleted",
      "default_field": "title"
    }
  }
}

Query String 支持完整的 Lucene 查询语法:

iPhone AND 15              → 必须包含两个词
iPhone OR Samsung          → 包含任意一个
title:"iPhone 15"          → title 字段短语匹配
price:[5000 TO 10000]      → 价格范围
-status:deleted            → 排除
iPhone~                    → 模糊匹配("iphne" 也能命中)
iPhone*                    → 通配符

适用场景:后台管理的高级搜索、内部工具。绝对不要让普通用户在搜索框里直接用 query_string——他们会输入 *:* 拉全量数据。

Match 全家桶对比

查询 分词 顺序敏感 得分计算 典型场景
match 每个 term 独立算分再汇总 通用搜索
match_phrase 顺序和位置一致性加分 标题搜索、专有名词
match_phrase_prefix ✅(最后一个 term 前缀) 同上 搜索框自动补全
match_bool_prefix ✅(最后一个 term 前缀) 高效前缀匹配 高性能自动补全
multi_match ❌(默认) 多字段综合评分 搜多个字段
query_string 支持 完整 Lucene 语法 后台高级搜索
simple_query_string 有限 简化语法,容错好 用户直接输入复杂搜索

Simple Query String:折中方案

match 强大,比 query_string 安全:

{
  "simple_query_string": {
    "query": "iPhone +Pro -mini | Samsung",
    "fields": ["title", "description"]
  }
}

语法:

  • + 必须包含
  • - 排除
  • |
  • "iPhone 15" 短语
  • * 通配符

适合:一个搜索框同时支持简单关键词和高级语法的场景。query_string 更安全——不会因为用户输入非法语法而直接报错。

真实选型指南

用户的输入是关键词 → match / multi_match
用户的输入是完整短语 → match_phrase (slop=0~3)
用户的输入需要容错 → match + minimum_should_match="75%"
用户边输入边搜 → match_phrase_prefix / match_bool_prefix
用户需要高级搜索(后台) → query_string
用户需要高级搜索(前台) → simple_query_string

总结

大部分生产搜索只需要三招:

  1. multi_match + best_fields 做关键词搜索
  2. match_phrase + slop 做精确短语匹配
  3. simple_query_string 给高端用户一个灵活但安全的搜索口

query_string 留给后台管理员用——它功能最强但也最危险。