文章目录
一、核心API结构
通过SearchRequest.source()
设置查询条件、分页参数和排序参数,三者属于同一级别:
SearchRequest request = new SearchRequest("index");
request.source()
.query(...) // 设置查询条件
.from(...) // 设置分页起始位置
.size(...) // 设置每页大小
.sort(...); // 设置排序条件
二、分页功能实现
1. 分页参数转换
前端参数 -> ES参数:
pageNumber
(页码) ->from
pageSize
(每页大小) ->size
转换公式:
int from = (pageNumber - 1) * pageSize;
int size = pageSize;
2. 代码实现示例
// 模拟前端传递参数
int pageNumber = 1; // 当前页码
int pageSize = 5; // 每页大小
// 设置分页
request.source()
.from((pageNumber - 1) * pageSize)
.size(pageSize);
三、排序功能实现
1. 单字段排序
// 按销量降序排序
request.source().sort("sales", SortOrder.DESC);
2. 多字段排序
// 主排序:销量降序,次排序:价格升序
request.source()
.sort("sales", SortOrder.DESC)
.sort("price", SortOrder.ASC);
3. 排序参数说明
SortOrder
枚举:ASC
:升序(默认)DESC
:降序
四、完整案例实现
需求说明:
- 查询所有数据
- 分页显示(第1页,每页5条)
- 主排序:库存降序
- 次排序:价格升序
Java代码实现
@Test
void testSortAndPage() throws IOException {
// 1. 创建请求对象
SearchRequest request = new SearchRequest("items");
// 2. 设置查询条件(查所有)
request.source().query(QueryBuilders.matchAllQuery());
// 3. 设置分页参数
int pageNumber = 1;
int pageSize = 5;
request.source()
.from((pageNumber - 1) * pageSize)
.size(pageSize);
// 4. 设置排序条件
request.source()
.sort("stock", SortOrder.DESC) // 库存降序
.sort("price", SortOrder.ASC); // 价格升序
// 5. 发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 6. 解析结果
parseResponse(response);
}
// 封装结果解析方法
private void parseResponse(SearchResponse response) {
SearchHits hits = response.getHits();
System.out.println("共查询到 " + hits.getTotalHits().value + " 条数据");
for (SearchHit hit : hits.getHits()) {
String json = hit.getSourceAsString();
ItemDoc doc = JSONUtil.toBean(json, ItemDoc.class);
System.out.println("doc = " + doc);
}
}
运行结果:
五、实际应用建议
1. 分页优化
- 深度分页问题:避免使用超过1000页的深度分页(ES默认限制10000条)
- 滚动查询:大数据量分页推荐使用
scroll
API
2. 排序扩展
- 地理排序:
sort(new GeoDistanceSortBuilder("location").point(lat, lon))
- 脚本排序:
.sort(SortBuilders.scriptSort(...))
3. 参数校验
// 校验分页参数有效性
if(pageNumber < 1) throw new IllegalArgumentException("页码不能小于1");
if(pageSize > 100) throw new IllegalArgumentException("单页大小不能超过100");
六、常见问题排查
1. 排序不生效
- 检查字段类型:
text
类型字段需要改用keyword
类型排序 - 检查字段是否存在:确认索引映射包含排序字段
2. 分页数据重复
- 确保排序字段组合能唯一确定顺序(建议包含
_id
字段)
3. 性能优化
- 对常用排序字段设置
doc_values: true
- 避免在分页查询中使用高开销排序(如脚本排序)