阶段:第二阶段 / 查询能力
ES 查询:range| PostgreSQL 对照:BETWEEN/>=/<=
1. 概念
range用于数值、日期、字符串的范围过滤。参数:
| 参数 | 含义 | SQL 对应 |
|---|---|---|
gt | 大于 | > |
gte | 大于等于 | >= |
lt | 小于 | < |
lte | 小于等于 | <= |
range通常放在filter上下文里(不需要相关性打分)。
2. PostgreSQL 对照
-- 数值范围SELECT*FROMsalesdataWHEREnet_amountBETWEEN1000AND5000;-- 日期范围SELECT*FROMsalesdataWHEREinvoice_dt>='2026-01-01'ANDinvoice_dt<'2026-07-01';3. ES DSL
数值范围
GET salesdata_idx/_search { "query": { "range": { "net_amount": { "gte": 1000, "lte": 5000 } } } }日期范围(支持日期数学表达式)
GET salesdata_idx/_search { "query": { "range": { "invoice_dt": { "gte": "2026-01-01", "lt": "2026-07-01" } } } }日期数学示例:"gte": "now-7d/d"表示「最近 7 天」,/d表示按天取整。
放进 filter(推荐)
{ "query": { "bool": { "filter": [ { "range": { "net_amount": { "gte": 1000 } } } ] } } }4. Spring Boot 实现
@ComponentpublicclassDoc12RangeQuery{@AutowiredprivateElasticsearchClientelasticsearchClient;/** net_amount BETWEEN min AND max */publicList<Map<String,Object>>byAmountRange(StringindexName,doublemin,doublemax)throwsIOException{SearchResponse<Map>resp=elasticsearchClient.search(s->s.index(indexName).query(q->q.range(r->r.field("net_amount").gte(JsonData.of(min)).lte(JsonData.of(max)))),Map.class);returntoSourceList(resp);}/** invoice_dt >= from AND invoice_dt < to */publicList<Map<String,Object>>byDateRange(StringindexName,Stringfrom,Stringto)throwsIOException{SearchResponse<Map>resp=elasticsearchClient.search(s->s.index(indexName).query(q->q.range(r->r.field("invoice_dt").gte(JsonData.of(from)).lt(JsonData.of(to)))),Map.class);returntoSourceList(resp);}privateList<Map<String,Object>>toSourceList(SearchResponse<Map>resp){returnresp.hits().hits().stream().map(Hit::source).filter(Objects::nonNull).collect(Collectors.toList());}}注意 import:
co.elastic.clients.json.JsonData。range的边界值在 8.x 客户端
用JsonData.of(...)包装,可传数值、字符串日期等。
5. 坑与最佳实践
gte/lte别混用成BETWEEN语义错误:BETWEEN是闭区间[a,b],对应gte + lte。- 日期字段要有正确 mapping:
type: date且format匹配写入格式,否则范围失效。 - 半开区间更安全:按天/月过滤时用
gte 起 + lt 下一个起点,避免边界重复。 - 放 filter:范围过滤几乎都不需要打分,放
filter更快、可缓存。 - 字符串 range 慎用:
keyword也能范围比较,但一般只对数值/日期有意义。
下一篇
13-bool-组合查询.md(最重要的一篇,AND/OR/NOT 全靠它)。