首页/云/可观测性速查/Term 与 Range:精确值与范围查询
日志平台52 条

Term 与 Range:精确值与范围查询

term 匹配不分词的精确值(keyword 字段),range 匹配数值与时间区间;两者是日志过滤中使用频率很高的原子条件。

可观测性速查云更新于 2026-10-13

term 与 range 是什么

term 是精确值匹配,range 是范围匹配,两者是 Elasticsearch 查询里出现频率最高的原子条件。term 不做分词,因此字段类型决定结果:对 text 字段用 term 往往查不到,因为存储的是分词后的词条,要用 keyword 子字段或改写成 match 查询。range 支持数值、日期与字符串区间,时间条件可以直接写相对表达式。

基本信息

适用引擎Elasticsearch 7.x / 8.x,DSL 语法基本一致
term 语义精确匹配,不分词
range 适用类型数值、日期、字符串(按字典序)
多值写法terms 一次匹配多个精确值,比多个 term 更简洁

典型使用场景

  • 日志过滤:按级别精确匹配只看错误级别日志
  • 耗时筛选:按 duration 区间找出慢请求
  • 时间窗口:限定时间范围拉取某次故障期间的文档
  • 状态码集合:一次匹配多个错误状态码
  • 多条件组合:在 bool 查询里用 term 与 range 混合过滤
  • 口径核对:用范围查询抽查某字段的取值分布是否落在预期区间

查询示例

查询示例
# term:精确匹配 keyword 字段
GET /logs-app/_search {"query": {"term": {"level.keyword": "error"}}}

# terms:一次匹配多个精确值
GET /logs-app/_search {"query": {"terms": {"level.keyword": ["error", "warn"]}}}

# range:数值区间
GET /logs-app/_search {"query": {"range": {"duration_ms": {"gte": 1000, "lt": 5000}}}}

# range:时间区间,支持相对表达式
GET /logs-app/_search {"query": {"range": {"@timestamp": {"gte": "now-1h"}}}}

# 组合:错误级别且耗时超过 1 秒
GET /logs-app/_search {"query": {"bool": {"filter": [{"term": {"level.keyword": "error"}}, {"range": {"duration_ms": {"gte": 1000}}}]}}}

参数与语义

写法含义注意
term单值精确匹配text 字段上不生效,改用 keyword
terms多值精确匹配值数量过多时性能下降
range 的 gte / gt大于等于 / 大于边界是否包含要明确
range 的 lte / lt小于等于 / 小于与告警口径保持一致
时间表达式now-1h 等相对写法服务端按请求时刻解析
match分词后匹配,非精确需要模糊匹配时用它而不是 term
过滤型条件放在 bool 查询的 filter 子句里可以利用缓存、不参与评分,日志检索场景下比 must 更合适。
字段类型决定查询行为:写入时把数值存成字符串,后续范围查询会按字典序比较,出现「9 比 10 大」这类错误结果。
字段名写错或后缀不对时的典型表现是命中数为零而不是报错,先用一条最小查询确认字段确实存在,再往上叠条件。

易错点

  • 对 text 字段用 term 查不到结果多半是分词导致,应改用 keyword 子字段或 match 查询
  • 数值型字段以字符串写入后范围查询结果异常,类型需在索引模板里固定
  • 时间区间边界写反(同时用两个 gte)会返回空结果且不报错,排查时先打印查询体
  • terms 一次传入成千上万个值会拖慢查询,这种情况改用范围或改用批量检索

数据来源与参考

  • Elastic 官方文档 · Term query / Range query
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌