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


  • 背景:

  • 实战

    • 测试主方法

    • 查询构造器

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

    • 导出实体类


背景:

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);
    }
}

开通了个微信公众号:

搜索:怒放de每一天

后续可能不定时推送相关文章,期待和大家一起成长!!

关注公众号

完,大功告成!


原文始发于微信公众号(怒放de每一天):elasticsearch使用 scroll 滚动分页实战实例

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/106842.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!