深入学习 ElasticSearch 的搜索(四):term 查询

term 查询用于精确词项匹配。

它和 match 最大的区别是:

match 会分析查询文本,term 不会按全文检索方式分析查询文本。

所以 term 更适合查结构化字段,例如分类、状态、标签、用户 ID、订单号等。


一、基本写法

查询分类是 elasticsearch 的文章:

POST article_search/_search
{
  "query": {
    "term": {
      "category": "elasticsearch"
    }
  }
}

这里的 categorykeyword 字段。

写入什么值,倒排索引里基本就是什么 term。

因此 term 查询可以精确命中。


二、term 查询适合 keyword 字段

例如 mapping 中:

{
  "category": {
    "type": "keyword"
  },
  "status": {
    "type": "keyword"
  },
  "author": {
    "type": "keyword"
  }
}

这些字段一般不需要分词。

查询时也通常不希望它被分析。

例如:

POST article_search/_search
{
  "query": {
    "term": {
      "status": "published"
    }
  }
}

这个查询表达的是:

只查状态精确等于 published 的文档。


三、term 查询 text 字段为什么容易查不到

这是初学者最常见的问题。

假设 titletext 字段,写入:

ElasticSearch 入门教程

索引时,字段会经过 analyzer,可能进入倒排索引的 term 是:

elasticsearch
入
门
教
程

这时如果查询:

POST article_search/_search
{
  "query": {
    "term": {
      "title": "ElasticSearch"
    }
  }
}

可能查不到。

原因是 term 不会把查询值自动分析成 elasticsearch

它会直接用 ElasticSearch 这个精确值去查倒排索引。

但倒排索引里实际可能是小写的:

elasticsearch

所以没有命中。


四、如果要查 text 字段,用 match

对于标题和正文这类 text 字段,一般使用:

POST article_search/_search
{
  "query": {
    "match": {
      "title": "ElasticSearch"
    }
  }
}

match 会分析查询文本,因此更适合全文检索。

记住:

text 字段 + 用户关键词搜索 -> match
keyword 字段 + 精确值过滤 -> term

五、terms:多个精确值匹配

如果要查询多个分类,可以使用 terms

POST article_search/_search
{
  "query": {
    "terms": {
      "category": ["elasticsearch", "redis"]
    }
  }
}

含义是:

category 是 elasticsearch 或 redis 的文档都返回。

这类似 SQL 中的:

WHERE category IN ('elasticsearch', 'redis')

要注意:

terms 的默认语义是“命中任意一个”,更像 SQL 的 IN,不是多个 term 的 AND 组合。

所以它没有 operator: "and" 这种参数。

如果业务要求“必须同时包含多个值”,应该考虑:

  • bool.must 中放多个 term
  • terms_set

例如要求 entity_names 同时包含 张三丰郭靖

POST article_search/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "entity_names": "张三丰"
          }
        },
        {
          "term": {
            "entity_names": "郭靖"
          }
        }
      ]
    }
  }
}

六、exists:判断字段是否存在

exists 用于判断某个字段是否有值。

POST article_search/_search
{
  "query": {
    "exists": {
      "field": "created_at"
    }
  }
}

如果要查某个字段不存在,可以放到 must_not 中:

POST article_search/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "exists": {
            "field": "created_at"
          }
        }
      ]
    }
  }
}

它适合:

  • 查缺失字段
  • 过滤字段不为空的数据
  • 做数据质量排查

七、range:数字和日期范围

range 用于范围查询。

它不是查“等于某个值”,而是查字段是否落在某个区间内。

查询浏览量大于 100 的文章:

POST article_search/_search
{
  "query": {
    "range": {
      "views": {
        "gt": 100
      }
    }
  }
}

查询某个时间范围内的文章:

POST article_search/_search
{
  "query": {
    "range": {
      "created_at": {
        "gte": "2026-04-01",
        "lte": "2026-04-30"
      }
    }
  }
}

四个常见边界参数:

  • gt:大于
  • gte:大于等于
  • lt:小于
  • lte:小于等于

可以简单理解:

  • term:查一个离散值
  • terms:查多个离散值
  • range:查一个连续区间

八、term 查询也会出现在 filter 中

在实际业务中,term 常常和 bool.filter 一起使用。

例如查询正文包含 ElasticSearch,并且状态是 published

POST article_search/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "content": "ElasticSearch"
          }
        }
      ],
      "filter": [
        {
          "term": {
            "status": "published"
          }
        }
      ]
    }
  }
}

这里:

  • match 负责全文检索,并参与评分
  • term 负责状态过滤,不参与评分

这是一种非常常见的组合。


九、term 查询和大小写

term 是精确词项查询,所以大小写很重要。

如果 keyword 字段中存的是:

Published

查询:

{
  "term": {
    "status": "published"
  }
}

就可能查不到。

解决方式通常有几种:

  • 写入时统一小写
  • 查询时统一小写
  • 使用 normalizer 处理 keyword 字段

对于分类、状态、枚举值,建议从数据设计阶段就统一格式。


十、term 查询适合什么场景

适合:

  • 分类
  • 状态
  • 标签
  • 用户 ID
  • 订单号
  • 枚举值
  • 是否启用
  • 已抽取的人名实体,例如 entity_names

不适合:

  • 文章正文全文搜索
  • 标题关键词搜索
  • 用户自然语言输入

十一、常见误区

1. term 不是全文搜索

term 不会像 match 一样分析查询文本。

所以不要用它来做普通关键词搜索。


2. term 查询 text 字段要非常小心

不是绝对不能查 text 字段,而是你必须知道该字段最终进入倒排索引的 term 是什么。

如果不知道,先用:

POST article_search/_analyze
{
  "field": "title",
  "text": "ElasticSearch 入门教程"
}

看清楚分词结果再判断。


3. keyword 字段不是不能用 match,但 term 更清楚

keyword 字段使用 match 有时也能命中。

但工程上更推荐用 term,因为语义明确,别人一看就知道这是精确匹配。


十二、一句话总结

term 查询用于精确词项匹配。

最重要的使用原则是:

查 text 字段的自然语言内容,用 match;查 keyword 字段的精确值,用 term。


参考链接

在这里插入图片描述

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐