精确查询

精确查询用于不进行分词的精确值匹配。这类查询直接与倒排索引中的 keyword 字段匹配,不经过分析过程,通常不参与相关性评分。

精确查询与全文检索的区别 #

精确查询与全文检索的核心差异在于:精确查询搜索文档中的确切词项,而全文检索会先对查询字符串进行分词分析

精确查询全文检索
描述回答"哪些文档匹配"回答"文档与查询的匹配程度"
分析器搜索词不被分析,按字面值匹配搜索词与文档字段使用相同分析器
相关性不根据相关性分数排序(所有匹配文档评分相同)计算相关性分数并按分数降序排序
用例精确值匹配(数字、日期、标签等 keyword 字段)文本字段的全文搜索

注意:精确查询不适合搜索分词后的 text 字段,通常会产生意想不到的结果(无匹配)。在处理文本数据时,仅将精确查询用于映射为 keyword 的字段。

示例:为什么 term 在 text 字段上搜不到? #

使用精确查询搜索 text_entry(text 字段)中的 “To be, or not to be”:

GET shakespeare/_search
{
  "query": {
    "term": {
      "text_entry": "To be, or not to be"
    }
  }
}

结果为 0 条匹配,因为倒排索引中存储的是分词后的小写词项(tobeornot),而 term 查询会将整个短语作为一个完整的词项去匹配。

改用 match 全文查询,则可以正确搜索到结果——搜索词会被分词后与倒排索引匹配,并按相关性排序。

示例:在 keyword 字段上使用精确查询 #

如果要在 speaker(keyword 字段)中搜索精确值 “HAMLET”:

GET shakespeare/_search
{
  "query": {
    "term": {
      "speaker": "HAMLET"
    }
  }
}

精确匹配返回 1582 条结果。注意必须大小写完全一致——搜索 “Hamlet” 将无匹配,因为 keyword 字段以原文形式存储。

查询类型 #

查询说明使用场景
term精确匹配单个值精确搜索(ID、状态码、分类等)
terms精确匹配多个值,任一匹配即可多选筛选
range范围查询(数值、日期)日期范围、价格范围、年龄范围
prefix前缀匹配(不分词)自动补全、标签前缀匹配
wildcard通配符匹配(? 单字符,* 多字符)灵活模式匹配
regexp正则表达式匹配(Lucene 语法)复杂模式匹配
fuzzy模糊匹配(编辑距离)拼写纠正、相似值查询
exists检查字段是否存在非空检查
ids按文档 ID 查询直接查询特定文档
terms_set动态词项匹配按最少匹配数筛选

特点 #

  • 不分词:精确匹配,不进行分词分析
  • 高效:通常不计算相关性评分,返回结果快
  • 在 filter 上下文中使用:常用于 bool 查询的 filter 子句
  • 缓存友好:适合作为过滤条件被缓存

推荐阅读顺序 #

  1. term:单值精确匹配
  2. terms:多值精确匹配
  3. range:范围查询
  4. prefix:前缀匹配
  5. wildcard:通配符
  6. regexp:正则表达式
  7. fuzzy:模糊匹配
  8. exists:存在性检查
  9. ids:ID 查询
  10. terms_set:动态匹配

常见用途 #

场景推荐查询
精确查找一个值term
精确查找多个值之一terms
日期范围筛选range
价格范围筛选range
自动补全前缀prefix
灵活的通配符匹配wildcard
拼写纠正fuzzy
检查字段是否为空exists