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

本文涉及的产品
Elasticsearch Serverless检索通用型,资源抵扣包 100CU*H
简介: 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可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
1月前
|
人工智能 自然语言处理 运维
让搜索引擎“更懂你”:AI × Elasticsearch MCP Server 开源实战
本文介绍基于Model Context Protocol (MCP)标准的Elasticsearch MCP Server,它为AI助手(如Claude、Cursor等)提供与Elasticsearch数据源交互的能力。文章涵盖MCP概念、Elasticsearch MCP Server的功能特性及实际应用场景,例如数据探索、开发辅助。通过自然语言处理,用户无需掌握复杂查询语法即可操作Elasticsearch,显著降低使用门槛并提升效率。项目开源地址:&lt;https://github.com/awesimon/elasticsearch-mcp&gt;,欢迎体验与反馈。
473 1
|
7月前
|
存储 运维 监控
超越传统模型:从零开始构建高效的日志分析平台——基于Elasticsearch的实战指南
【10月更文挑战第8天】随着互联网应用和微服务架构的普及,系统产生的日志数据量日益增长。有效地收集、存储、检索和分析这些日志对于监控系统健康状态、快速定位问题以及优化性能至关重要。Elasticsearch 作为一种分布式的搜索和分析引擎,以其强大的全文检索能力和实时数据分析能力成为日志处理的理想选择。
506 6
|
6月前
|
测试技术 API 开发工具
ElasticSearch7.6.x 模板及滚动索引创建及注意事项
ElasticSearch7.6.x 模板及滚动索引创建及注意事项
107 8
|
7月前
|
缓存 关系型数据库 API
京东面试题:ElasticSearch深度分页解决方案!
京东面试题:ElasticSearch深度分页解决方案!
109 0
|
10月前
|
存储 数据采集 数据处理
数据处理神器Elasticsearch_Pipeline:原理、配置与实战指南
数据处理神器Elasticsearch_Pipeline:原理、配置与实战指南
410 12
|
9月前
|
自然语言处理 前端开发 Java
ElasticSearch 实现分词全文检索 - Scroll 深分页
ElasticSearch 实现分词全文检索 - Scroll 深分页
74 0
|
10月前
|
数据库
面试题ES问题之Elasticsearch的排序分页和高亮功能如何解决
面试题ES问题之Elasticsearch的排序分页和高亮功能如何解决
79 0
|
11月前
|
缓存 数据处理 数据安全/隐私保护
Elasticsearch索引状态管理实战指南
Elasticsearch索引状态管理实战指南
144 0
|
11月前
|
存储 数据库 开发者
Elasticsearch中的三种分页策略深度解析:原理、使用及对比
Elasticsearch中的三种分页策略深度解析:原理、使用及对比
|
11月前
|
存储 索引
Elasticsearch索引之嵌套类型:深度剖析与实战应用
Elasticsearch索引之嵌套类型:深度剖析与实战应用