查询
一、客户端选型
简单场景:Spring Data Elasticsearch,分为:ElasticsearchRepository、RestHighLevelClient、ElasticsearchOperations。
- ElasticsearchRepository:接口,通过方法名自动生成查询,零手写 DSL 就能完成 CRUD、基础分页、关键词检索,开发效率拉满。
- RestHighLevelClient:遗留系统维护(Spring Boot 2.x + ES 7.x);Spring Boot 3 要求构建和运行环境都是 JDK 17+。
- ElasticsearchOperations:要求 Spring Boot 3,SDE 标准做法,平衡了易用性和性能,支持对象映射。
复杂场景:Elasticsearch Java API Client,原生 ElasticsearchClient。直接注入 Spring 自动装配好的原生 ElasticsearchClient,可以直接调用 ES 所有原生 API,支持自定义复杂聚合、脚本排序、BulkIngester 高性能批量写入等高级操作,没有封装层的能力阉割,性能和直接调用原生客户端完全一致。
二、查询语法
1. 查询关键词所在上下文(query-bool 下)
- must下:
match、match_phrase、multi_match - filter下:
term、terms、range、exists - should下:同
must - must_not下:同
filter
2. 各子句语义
- must:必须匹配,会打分(AND + Score)。
- filter:必须匹配,不打分(AND + No Score + Cachable)。
- should:可选匹配,加分项(OR + Score)。
- must_not:必须不匹配,不打分(NOT + No Score + Cachable)。
- bool:逻辑容器,组合以上。
3. 形象化理解
- must & should:“会打分的裁判”。它们根据查询词在文档中的匹配程度(如出现频率、字段权重等)给出一个相关性分数(
_score),最终文档按此分数排序。 - filter & must_not:“不记分的筛选器”。它们只做"是/否"的二元判断(匹配/不匹配),不产生任何分数。ES 会自动缓存这些查询结果,因此速度更快,适合频繁执行的过滤条件。
- must & filter:像漏斗,不断缩小结果集。
- should:像加分项,不改变结果集,但改变排序。
- must_not:像筛子,从结果中剔除特定文档。
4. 完整示例
GET /products/_search { "query": { "bool": { // 1. 全文搜索部分:参与评分,决定排序 "must": [ { "multi_match": { "query": "华为 智能手机 5G", "fields": [ "name^3", // 名称字段权重为3 "description^2", // 描述字段权重为2 "tags" // 标签字段权重为1 ], "type": "best_fields" // 取最高分字段的分数 } } ], // 2. 精确过滤部分:不参与评分,可缓存,性能高 "filter": [ { "term": { "status": "active" } }, // 只显示在售商品 { "range": { "price": { "gte": 1000, "lte": 5000 } } }, // 价格范围 { "terms": { "brand": ["huawei", "honor"] } } // 品牌是华为或荣耀 ], // 3. 排除部分:不参与评分,可缓存 "must_not": [ { "term": { "category": "refurbished" } }, // 排除翻新机 { "term": { "seller_rating": "low" } } // 排除低评级卖家 ], // 4. 可选加权部分:参与评分,提升特定商品的排名 "should": [ { "term": { "is_premium": true } }, // 优先展示高级商品 { "term": { "is_free_shipping": true } }, // 优先展示包邮商品 { "range": { "sales_count": { "gte": 1000 } } } // 优先展示销量高的商品 ], // 5. 控制should匹配数量:即使没有匹配任何should子句,文档也能被返回 "minimum_should_match": 0 } }, "sort": [ { "_score": { "order": "desc" } }, // 首先按相关度评分排序 { "sales_count": { "order": "desc" } } // 评分相同时,按销量降序 ], "from": 0, "size": 10 }三、聚合
1. 聚合模板
"aggs": { "聚合名称": { "聚合类型": { "聚合参数": {} } } }- 聚合名称:自定义
- 聚合类型:
terms - 聚合参数:
field: "xxx.keyword"
2. 例子
GET /bank/_search { "size": 0, "aggs": { "group_by_state": { "terms": { "field": "state.keyword" } } } }