Java elasticsearch scroll模板实现

这篇具有很好参考价值的文章主要介绍了Java elasticsearch scroll模板实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、scroll说明和使用场景

scroll的使用场景:大数据量的检索和操作

scroll顾名思义,就是游标的意思,核心的应用场景就是遍历 elasticsearch中的数据;

通常我们遍历数据采用的是分页,elastcisearch还支持from size的方式进行分页查询,使用 from and size 的深度分页,比如说 ?size=10&from=10000,因为 100,000 排序的结果必须从每个分片上取出并重新排序最后返回 10 条。这个过程需要对每个请求页重新进行提取+排序,效率很低,消耗很大,所以默认的最大可分页的数据是10000,超过10000是不建议的;

使用

通过在url末尾带上scroll=1m表示开启一个游标,1m表示游标的有效期为1分钟

POST /record/_search?scroll=1m
{
  "from": 0,
  "size": 20
}

返回结果中会把scroll的id带上,再次查询的时候,直接用scroll id查询即可

Java elasticsearch scroll模板实现,java

POST /_search/scroll
{
    "scroll" : "1m", 
    "scroll_id" : "FGluY2x1ZGVfY29udGV4dF91dWlkDnF1ZXJ5VGhlbkZldGNoAhZuYmpMbVpwWFRUMnNFMUFFSHlSMHB3AAAAAALBy_0WUWxrNTRTaWNUcy1sOHQ0VUo5dzF6dxZoemFkZTlMeFQ4MmoyOW5SUG8ybE53AAAAAAN6ip8WMmk5TWZlQ21RQnFsNURwaXRzSGhCdw==" 
}

二、基于ElasticsearchRestTemplate的实现

这里我们定义了一个template如下,主要作用就是实现一个基于scroll的数据遍历模板,屏蔽开启scroll 以及 scroll遍历所有数据,通过Consumer<T>钩子函数进行数据处理

import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchScrollHits;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;

import java.util.List;
import java.util.concurrent.*;

/**
 * scrollTemplate 模板,用于遍历整个Index的数据
 * @author xiuzhu
 * @Date 2023/7/28 13:12
 */
@Slf4j
public class ElasticSearchScrollTemplate<T> {

    ExecutorService executorService = new ThreadPoolExecutor(1, 4,
                                      30,TimeUnit.SECONDS,
                                      new LinkedBlockingQueue<Runnable>(5),
                                        Executors.defaultThreadFactory(),
                                        new ThreadPoolExecutor.CallerRunsPolicy()
                                    );

    ElasticsearchRestTemplate elasticSearchRestTemplate;

    Class<T> cls;

    String indexName;

    public ElasticSearchScrollTemplate(
            ElasticsearchRestTemplate template,
            Class<T> cls,
            String indexName
    ) {
        this.elasticSearchRestTemplate = template;
        this.cls = cls;
        this.indexName = indexName;
    }

    @FunctionalInterface
    public interface Consumer<T> {
        public void accept(List<T> objects);
    }

    public void execute(Consumer<T> consumer) {
        //构建查询条件
        NativeSearchQueryBuilder query = new NativeSearchQueryBuilder();
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();

        query.withPageable(PageRequest.of(0, 300));
        query.withQuery(queryBuilder);

        //保留0.5分钟
        long scrollTimeInMillis = 30*1000;

        IndexCoordinates recordIndex = IndexCoordinates.of(indexName);
        SearchScrollHits<T> hits = elasticSearchRestTemplate.searchScrollStart(scrollTimeInMillis, query.build(), cls, recordIndex);

        // scrollId
        String scrollId = hits.getScrollId();
        List<T> recordEntityList = hits.stream().map(SearchHit::getContent).toList();
        long total = 0L;

        log.info("================ began scroll index={} ====================", indexName);

        executorService.submit(()->{
            consumer.accept(recordEntityList);
        });

        total = total + recordEntityList.size();

        log.info("================  has scroll index={} total={} ====================", indexName, total);
        while (!hits.isEmpty()) {
            hits = elasticSearchRestTemplate.searchScrollContinue(scrollId, scrollTimeInMillis, cls, recordIndex);
            List<T> entities = hits.stream().map(SearchHit::getContent).toList();

            executorService.submit(()->{
                consumer.accept(entities);
            });

            total = total + entities.size();
            try {
                //给系统留GC时间,不然容易内存溢出
                Thread.sleep(300);
            } catch (InterruptedException e) {
                log.error("sleep error", e);
            }
            log.info("================  has scroll index={} total={} ====================", indexName, total);
        }
        log.info("================ end scroll index={} ====================", indexName);
    }
}

使用参考:

@Resource(name = "elasticSearchRestTemplate")
    ElasticsearchRestTemplate elasticsearchRestTemplate;

new ElasticSearchScrollTemplate<>(
                        elasticsearchRestTemplate,
                        RecordEntity.class,
                        "record")
                ).execute((entities)->{
                    entities.forEach(item->{
                        //这里进行数据的处理,比如修改数据
                        recordEntityService.save(item);
                        log.info("tag update success record={} api={}", item.getId());

                    });
                });

本文由mdnice多平台发布文章来源地址https://www.toymoban.com/news/detail-694681.html

到了这里,关于Java elasticsearch scroll模板实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • <Java导出Excel> 1.0 Java实现Excel动态模板导出

    思路: 1,先创建动态模板(必须要在数据库建一张表,可随时修改模板) 例如: 建表语句: 模板中的字段脚本: 2,编写一个查询接口:返回一个List map 注意:order by id 根据表中字段:id排序的作用是控制导出的EXCEL表中字段列的顺序; mapper.xml层: mapper接口层: serviceIm

    2024年02月12日
    浏览(49)
  • Java下载Excel模板文件的实现

    在项目中经常会用到文件下载的功能,比如下载excel模板,这里简单记录一下实现过程 1、将模板文件放到项目资源文件目录中,也可以自定义其他位置,只要通过路径能找到该文件就行:  2、controller层写下载的接口 3、前端直接调用这个接口就可以实现下载啦

    2024年02月11日
    浏览(47)
  • Elasticsearch 使用scroll滚动技术实现大数据量搜索、深度分页问题 和 search

    基于scroll滚动技术实现大数据量搜索 如果一次性要查出来比如10万条数据,那么性能会很差,此时一般会采取用scroll滚动查询,一批一批的查,直到所有数据都查询完为止。 scroll搜索会在第一次搜索的时候,保存一个当时的视图快照,之后只会基于该旧的视图快照提供数据搜

    2024年02月14日
    浏览(53)
  • 如何使用Java 实现excel模板导出---多sheet导出?

    效果展示: maven依赖 相关工具类 **此处省略异常处理类 ExcelReportUtil 类 excel 接口 实现类 excel填充数据处理类 excel填充处理类 excel模板处理 实现关键代码展示 通过模板实现导出功能 ExcelReportCreator 中的代码 导入数据案例展示 excel模板批注案例 每个sheet页都需要写批注,通过批

    2024年02月15日
    浏览(45)
  • java集成itextpdf实现通过pdf模板填充数据生成pdf

    我采用的是pdfelement 官网地址需要付费或者自行破解,也可以使用其他pdf编辑器。 将制作好的pdf模板放入项目resources/pdf目录下,如图 浏览器访问ip:port/test/pdf,其中ip为你的ip地址,port为你的端口,访问结果如下:

    2024年02月16日
    浏览(42)
  • ElasticSearch系列 - SpringBoot整合ES:实现分页搜索 from+size、search after、scroll

    01. 数据准备 ElasticSearch 向 my_index 索引中索引了 12 条文档: 02. ElasticSearch 如何查询所有文档? ElasticSearch 查询所有文档 根据查询结果可以看出,集群中总共有12个文档,hits.total.value=12, 但是在 hits 数组中只有 10 个文档。如何才能看到其他的文档? 03. ElasticSearch 如何指定搜

    2023年04月08日
    浏览(47)
  • JAVA实现向Word模板中插入Base64图片和数据信息

    在服务端提前准备好Word模板文件,并在用户请求接口时服务端动态获取图片。数据等信息插入到模板当中,然后返回包含数据信息的Word文件流。 在需要插入图片的地方使用:{{@参数名}},文本信息使用:{{参数名}},进行占位,占位格式将会被保留,经过处理后格式不变 将准

    2024年01月19日
    浏览(36)
  • Java实现创建链表与打印链表元素(可作为模板)

    1、通过数组元素值,构造一个单向链表; 2、将链表元素以数组的形式打印出来,如“[1, 2, 3, 4]”

    2024年02月05日
    浏览(40)
  • Elasticsearch分组--- java api 实现

    这篇文章 将已实战的方式带你 实现es 的各种分组操作

    2024年02月12日
    浏览(71)
  • 【ElasticSearch】数据聚合语法与Java实现

    聚合(aggregations)可以实现 对文档数据的统计、分析、运算 。(类比MySQL的聚合函数)ES聚合常见的有三类: 桶(Bucket)聚合:用来对文档做分组 度量(Metric)聚合:用以计算一些值,比如:最大值、最小值、平均值等 管道(pipeline)聚合:基于其它聚合的结果为基础做聚

    2024年02月14日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包