elasticsearch使用 scroll 滚动分页实战实例

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: elasticsearch使用 scroll 滚动分页实战实例


背景:

es使用page查询时,会有10000条数据限制,超过10000条就报错,查不出来了,不过可以使用scroll滚动分页来做查询。

实战

本例使用es的scroll查询,然后获取每一个scrollid对应的数据,进行自己的业务逻辑处理,最后将业务数据导出。

测试主方法

/**
     * 滚动导出每日行程
     *
     * @param startTime
     * @param endTime
     * @param response
     * @throws IOException
     */
    @GetMapping("/test10")
    public void test10(String startTime, String endTime, HttpServletResponse response) throws IOException {
        //最终导出的数据集合
        List<VehicleRechargeVo> resultList = new ArrayList<>();
        int pageNo = 0;
        //每次获取9000条数据
        int pageSize = 9000;
        //查询条件构建
        SearchQuery searchQuery = getSearchQuery2(startTime, endTime, pageNo, pageSize);
        //组装数据
        List<VehicleRechargeVo> pageList = new ArrayList<>();
        List<BusinessVehicleRecharge> pageContent = null;
        // 滚动查询
        ScrolledPage<BusinessVehicleRecharge> scroll = elasticsearchTemplate.startScroll(5000, searchQuery, BusinessVehicleRecharge.class);
        // 判断是否有内容
        while (scroll.hasContent()) {
            pageContent = scroll.getContent();
            //拿出每一scrollId对应的数数据并处理自己的业务
            pageList = combineData2(pageContent);
            //将上面的数据加入最终集合中
            resultList.addAll(pageList);
            //取下一页,scrollId在es服务器上可能会发生变化,需要用最新的。发起continueScroll请求会重新刷新快照保留时间
            scroll = elasticsearchTemplate.continueScroll(scroll.getScrollId(), 5000, BusinessVehicleRecharge.class);
        }
        // 最后释放查询,必须释放
        elasticsearchTemplate.clearScroll(scroll.getScrollId());
        // 下面是使用easyExcel做导出
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("每日充电明细统计", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), VehicleRechargeVo.class)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .sheet("每日充电明细统计")
                .doWrite(resultList);
    }

查询构造器

private SearchQuery getSearchQuery2(String startTime, String endTime, int pageNo, int pageSize) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withIndices("business_vehicle_XXX").withTypes("_doc")
                .withSort(SortBuilders.fieldSort("dateStr").order(SortOrder.ASC))
                .withPageable(PageRequest.of(pageNo, pageSize))
                .withSourceFilter(
                        new FetchSourceFilterBuilder().withIncludes("dateStr", "vin", "startTime", "endTime",
                                "rechargePower", "rechargeTimes", "socStartTime", "socEndTime")
                                .build())
                .build();
        return searchQuery;
    }

对每一scroll Id对应的分页数据做些处理

combineData2

private List<VehicleRechargeVo> combineData2(List<BusinessVehicleRecharge> content) {
        List<VehicleRechargeVo> list = new ArrayList<>();
        content.stream().forEach(item -> {
            if (StringUtils.isNotBlank(item.getDateStr())) {
                VehicleRechargeVo rechargeVo = new VehicleRechargeVo();
                rechargeVo.setDateStr(item.getDateStr());
                rechargeVo.setVin(item.getVin());
                rechargeVo.setStartTime(item.getStartTime());
                rechargeVo.setEndTime(item.getEndTime());
                rechargeVo.setSocStartTime(item.getSocStartTime());
                rechargeVo.setSocEndTime(item.getSocEndTime());
                rechargeVo.setRechargePower(item.getRechargePower());
                rechargeVo.setRechargeTimes(item.getRechargeTimes());
                list.add(rechargeVo);
            }
        });
//        Collections.sort(list);
        return list;
    }

导出实体类

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.io.Serializable;
/**
 * @Auther: hfl
 * @Date: 2022/3/15
 * @Description: 导出充电明细
 */
@Data
public class VehicleRechargeVo implements Serializable,Comparable<VehicleRechargeVo> {
    @ExcelProperty(value = "日期")
    private String dateStr;
    @ExcelProperty(value = "VIN")
    private String vin;
    /**
     * 充电开始时间
     */
    @ExcelProperty(value = "充电开始时间")
    private String startTime;
    /**
     * 充电结束时间
     */
    @ExcelProperty(value = "充电结束时间")
    private String endTime;
    /**
     * 充电电量 kw.h
     */
    @ExcelProperty(value = "充电电量 kw.h")
    private float rechargePower;
    /**
     * 充电时长 h
     */
    @ExcelProperty(value = "充电时长 h")
    private float rechargeTimes;
    /**
     * SOC开始时间
     */
    @ExcelProperty(value = "SOC开始时间")
    private float socStartTime;
    /**
     * SOC结束时间
     */
    @ExcelProperty(value = "SOC结束时间")
    private float socEndTime;
    @Override
    public int compareTo(VehicleRechargeVo o) {
        return this.dateStr.compareTo(o.dateStr);
    }
}


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
19天前
|
测试技术 API 开发工具
ElasticSearch7.6.x 模板及滚动索引创建及注意事项
ElasticSearch7.6.x 模板及滚动索引创建及注意事项
33 8
|
1月前
|
缓存 关系型数据库 API
京东面试题:ElasticSearch深度分页解决方案!
京东面试题:ElasticSearch深度分页解决方案!
|
4月前
|
存储 数据采集 数据处理
数据处理神器Elasticsearch_Pipeline:原理、配置与实战指南
数据处理神器Elasticsearch_Pipeline:原理、配置与实战指南
175 12
|
3月前
|
自然语言处理 前端开发 Java
ElasticSearch 实现分词全文检索 - Scroll 深分页
ElasticSearch 实现分词全文检索 - Scroll 深分页
40 0
|
4月前
|
数据库
面试题ES问题之Elasticsearch的排序分页和高亮功能如何解决
面试题ES问题之Elasticsearch的排序分页和高亮功能如何解决
38 0
|
5月前
|
缓存 数据处理 数据安全/隐私保护
Elasticsearch索引状态管理实战指南
Elasticsearch索引状态管理实战指南
|
5月前
|
存储 数据库 开发者
Elasticsearch中的三种分页策略深度解析:原理、使用及对比
Elasticsearch中的三种分页策略深度解析:原理、使用及对比
|
5月前
|
存储 索引
Elasticsearch索引之嵌套类型:深度剖析与实战应用
Elasticsearch索引之嵌套类型:深度剖析与实战应用
|
5月前
|
存储 数据采集 负载均衡
Elasticsearch系列---搜索执行过程及scroll游标查询
Elasticsearch系列---搜索执行过程及scroll游标查询
|
5月前
|
存储 JSON 搜索推荐
Springboot2.x整合ElasticSearch7.x实战(三)
Springboot2.x整合ElasticSearch7.x实战(三)
47 0