ES Search After 分页查询
需求分析,如上图
对基金经理数据进行分页查询,并可根据年化回报率,综合得分进行排序
Seach After 两点比较重要:排序字段 排序字段值
1.排序字段一定要包含唯一值字段,即不重复,可用es自带id,因为排序的原理,类似数据库深度分页,条件包含上一页最后一条数据ID,效率比较高,同理要把这个唯一值作为下一页查询条件
2.如果没有业务相关的排序字段(无上年化回报,综合得分)怎么查询
排序字段默认为es默认_id,且倒序,srollId作为下页查询条件
3.查询包含业务条件时,需要注意排序字段包含业务条件,且排序顺序,先根据业务条件排序,再根据_id排序,同时要传入上一页排序字段的值及srollId
4.首页查询时排序字段值怎么传,如果不传会有问题,可以根据排序是升序,降序传入固定值,
如果是desc,其他页排序字段值肯定比它小,排序字段值传最大,可传101
如果是asc,其他页排序字段值肯定比它大,排序字段值传最小,可传-1
其他需要注意的地方
对比
使用search_after 进行分页 相比from&size的方式要更加高效,而且在不断有新数据入库的时候仅仅使用from和size分页会有重复的情况
相比使用scroll分页,search_after可以进行实时的查询
不过search_after不适合跳跃式的分页
注意事项
1,类似mysql limit offset size,进行分页查询时,取上一页最后一条数据的id;
2,如果是多个字段排序的话,search_after值的顺序要与我们排序条件的顺序一致,此处ID倒序
3,使用search_after时 from设置为0,-1或者直接不加from
代码
@Overridepublic Page<FundManagerDTO> page(ManagerEsReqDto reqDto) {if (StringUtils.isBlank(reqDto.getOrderBy())) {reqDto.setOrderBy("returnProportion");}if (StringUtils.isBlank(reqDto.getSort())) {reqDto.setSort("desc");}/*首页可不传,不影响结果*/if (StringUtils.isBlank(reqDto.getScrollId())) {log.info("manager The paging query failed, Param is empty. req: {}", JSON.toJSONString(reqDto));}/*回报率可能为0或负值,首页查询赋值,前端可不传*/if (1 == reqDto.getPage() && "desc".equalsIgnoreCase(reqDto.getSort())) {reqDto.setOrderByValue(101);}if (1 == reqDto.getPage() && "asc".equalsIgnoreCase(reqDto.getSort())) {reqDto.setOrderByValue(-1);}com.zgzt.common.util.Page<FundManagerDTO> page = new com.zgzt.common.util.Page<>();BoolQueryBuilder params = buildQueryBuilder();SearchRequest searchRequest = buildSearchRequest(EsOperateTables.manager, params, reqDto.getSize(),reqDto.getOrderBy(), reqDto.getOrderByValue(), reqDto.getSort(), reqDto.getScrollId());try {List<FundManagerDTO> list = search(searchRequest, page);page.setResult(list);page.setPageNo(reqDto.getPage());page.setPageSize(reqDto.getSize());return page;} catch (Exception e) {log.error("manager The paging query exception", e);throw ExceptionUtils.throwException(MANAGER_QUERY_ERROR);}}
private BoolQueryBuilder buildQueryBuilder() {BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();return boolQueryBuilder;}private SearchRequest buildSearchRequest(EsOperateTables esOperateTables, QueryBuilder params, int pageSize,String orderBy, double orderByValue, String sort, String scrollId) {if (pageSize > 10000) {pageSize = 10000;}SearchRequest searchRequest = new SearchRequest(esOperateTables.getValue());SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();sourceBuilder.query(params);sourceBuilder.from(0);sourceBuilder.size(pageSize);sourceBuilder.timeout(new TimeValue(10, TimeUnit.SECONDS));if (esOperateTables.getSelectCols() != null && esOperateTables.getSelectCols().length > 0) {sourceBuilder.fetchSource(esOperateTables.getSelectCols(), new String[] {});}FieldSortBuilder fieldOderby;if (SortOrder.ASC.toString().equalsIgnoreCase(sort)) {fieldOderby = SortBuilders.fieldSort(orderBy).order(SortOrder.ASC);} else {fieldOderby = SortBuilders.fieldSort(orderBy).order(SortOrder.DESC);}FieldSortBuilder fieldId = SortBuilders.fieldSort("_id").order(SortOrder.DESC);sourceBuilder.sort(fieldOderby).sort(fieldId);sourceBuilder.searchAfter(new Object[] { orderByValue, scrollId });searchRequest.source(sourceBuilder);return searchRequest;}
@Data
public class ManagerEsReqDto extends BasePageDto {@ApiModelProperty("上一页最后数据_ID,必填字段,首页可不存")private String scrollId;@ApiModelProperty("上一页最后数据_业务排序字段值,必填字段,首页可不传")private double orderByValue;
}
@Data
public class BasePageDto {@ApiModelProperty("当前页数")private Integer page = 1;@ApiModelProperty("每页条数")private Integer size = 10;@ApiModelProperty("排序字段")private String orderBy;@ApiModelProperty("排序规则(升序:asc/倒序:desc)")private String sort;}
Elasticsearch 深入理解search After 处理深度分页问题_wangxuelei036的博客-CSDN博客_search_after
这篇文章实现思路也可以,DSL语句写法,注意两点
1.排序字段,业务排序字段在前,文档_id在后
2.排序值,业务排序值在前,主键值在后
ES Search After 分页查询相关推荐
- 解决es分组后分页查询的问题
今天碰到的问题:es查询中携带了分组查询,导致进行分页操作的时候冲突,不能实现分页功能,后进行改良(抄同事代码),可以实现分页查询 int limit = paging.getLimit(); int ...
- ES中实现分页查询数据并返回想要的字段
在日志收集系统中,最近需要通过httpclient获取es中的日志信息,所以学习了一些es的查询语句方面的用法: 分页 分页的本质 分页的本质是从"大的数据集"中取出一部分.比如1 ...
- es分页查询重复数据_ES优化 - 巨量数据如何提高查询性能
问题:如果数据量特别大,如何优化ES的查询性能? 可以从以下几个方面进行思考: File Cache可用的内存: ES的查询严重依赖OS的File Cache,所以说内存分配的内存肯定是越多越好.最理 ...
- php 分页 查询 es,php-如何使分页elasticsearch?
我是Elasticsearch的新手. 我不知道要分页. 我的代码: require_once 'app/init.php'; if(isset ($_GET['q'])) { $q = $_GET[ ...
- ElasticSearch系列 - SpringBoot整合ES:实现分页搜索 from+size、search after、scroll
文章目录 01. 数据准备 02. ElasticSearch 如何查询所有文档? 03. ElasticSearch 如何指定搜索结果的条数? 04. ElasticSearch 分页查询方式有哪些 ...
- ES深度分页查询详解
一.ES支持的三种分页查询方式 From + Size 查询 Scroll 遍历查询 Search After 查询 说明: 官方已经不再推荐采用Scroll API进行深度分页.如果遇到超过1000 ...
- ES分页查询时报错“Result window is too large ...”
ES分页查询时报错"Result window is too large ..." 问题出现缘由 报错详情 错误译文 解决办法 问题出现缘由 ES 中存储了索引数据,使用 ES 可 ...
- Spring Boot操作ES进行各种高级查询(值得收藏)
作者 | 后青春期的Keats 来源 | http://cnblogs.com/keatsCoder/p/11341835.html SpringBoot整合ES 创建SpringBoot项目,导入 ...
- elasticsearch java 分页查询_elasticsearch深度分页问题
正版包邮elasticsearch实战与原理 70.1元 包邮 (需用券) 去购买 > elasticsearch分页对于用过es的人应该都会使用 ,和数据库的分页类似,如下所示,通过from ...
- 【纯干货】SpringBoot 整合 ES 进行各种高级查询搜索
在上篇 SpringBoot 整合 ElasticSearch 文章中,我们详细的介绍了 ElasticSearch 的索引和文档的基本增删改查的操作方法! 本文将重点介绍 ES 的各种高级查询写法和 ...
最新文章
- 20.27 分发系统介绍 20.28 expect脚本远程登录 20.29 expect脚本远程执行
- BUUCTF(Pwn) rip
- web页面屏蔽鼠标右键
- Shell脚本中函数返回值的用法笔记
- 园林系统优秀党员推荐材料_园林绿化公司党员先进个人事迹材料
- 【原创】OllyDBG 入门系列(七)-汇编功能
- ant构建异常UNEXPECTED TOP-LEVEL EXCEPTION com.android.dx.cf.iface.ParseException解决
- pdf转图片在线转换免费
- SpringBoot项目yml文件 不显示绿色小树叶的问题
- Win10怎么设置不进入屏保也不关闭显示器
- 如何用markdown排版公众号,使用排版神器Markdown Nice
- 金融数据api接口记录(二)
- PX4源码分析__传感器数据“sensor_combined”的来龙去脉
- 聊天的技巧,你是怎样和别人聊天的
- thinkpad e450c蓝牙重新安装后不能搜索到手机解决方案--适用大部分笔记本
- selenium优缺点_Selenium测试自动化工具的优缺点
- RIV A128显卡维修
- 舍友整日沉迷代码?偷偷给他的idea装上防沉迷插件!!
- “大数据”如何驱动世界的未来?
- 基于Matlab闭环Buck降压斩波电路Simulink仿真电路模型搭建
热门文章
- Windows平台上实现P2P服务(一)
- sicp 3.9题解答
- 0.python class
- Netflix是如何针对云构建和部署代码的
- c语言小树苗健康指数,一颗特别的小树苗.doc
- Linux链表list_head/hlist_head/hlist_nulls_head的并发性
- FRR BGP协议分析10 -- 路由衰减
- 请求发送者与接收者解耦——命令模式(三)
- Linux虚拟文件系统(内核初始化一)
- DIV_ROUND_CLOSEST函数