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可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
5月前
|
前端开发 Java Docker
利用 docker 部署 elasticsearch 集群(单节点多实例)
利用 docker 部署 elasticsearch 集群(单节点多实例)
254 0
|
5月前
|
存储 人工智能 自然语言处理
ElasticSearch实战指南必知必会:安装分词器、高级查询、打分机制
ElasticSearch实战指南必知必会:安装分词器、高级查询、打分机制
ElasticSearch实战指南必知必会:安装分词器、高级查询、打分机制
|
4月前
|
安全 大数据 API
elasticsearch|大数据|elasticsearch的api部分实战操作以及用户和密码的管理
elasticsearch|大数据|elasticsearch的api部分实战操作以及用户和密码的管理
62 0
|
6月前
|
存储 关系型数据库 数据库
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
|
1月前
|
消息中间件 Java 关系型数据库
【二十】springboot整合ElasticSearch实战(万字篇)
【二十】springboot整合ElasticSearch实战(万字篇)
195 47
|
4月前
|
JSON 数据格式
elasticsearch 实战(二)
elasticsearch 实战
35 0
|
4月前
|
JSON Java API
elasticsearch 实战(一)
elasticsearch 实战
64 0
|
4月前
|
JavaScript Java 开发工具
ElasticSearch实战 之 es的安装和使用
ElasticSearch实战 之 es的安装和使用
138 0
|
5月前
|
存储 人工智能 API
Elasticsearch实战:常见错误及详细解决方案
Elasticsearch实战:常见错误及详细解决方案
|
8天前
|
数据可视化 索引
elasticsearch head、kibana 安装和使用
elasticsearch head、kibana 安装和使用