百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 文章教程 > 正文

ElasticSearch教程之---Scroll查询

xsobi 2024-11-26 10:12 1 浏览


作者:千锋老魏

源码地址:https://github.com/qfjiaoyan/elasticsearch-examples


ES对于from+size的个数是有限制的,二者之和不能超过1w。当所请求的数据总量大于1w时,可用scroll来代替from+size。

1.7.1 原理

ES的搜索是分2个阶段进行的,即Query阶段和Fetch阶段。 Query阶段比较轻量级,通过查询倒排索引,获取满足查询结果的文档ID列表。 而Fetch阶段比较重,需要将每个shard的结果取回,在协调结点进行全局排序。 通过From+size这种方式分批获取数据的时候,随着from加大,需要全局排序并丢弃的结果数量随之上升,性能越来越差。

而Scroll查询,先做轻量级的Query阶段以后,免去了繁重的全局排序过程。 它只是将查询结果集,也就是doc id列表保留在一个上下文里, 之后每次分批取回的时候,只需根据设置的size,在每个shard内部按照一定顺序(默认doc_id续), 取回这个size数量的文档即可。

1.7.2 使用场景

由此也可以看出scroll不适合支持那种实时的和用户交互的前端分页工作,其主要用途用于从ES集群分批拉取大量结果集的情况,一般都是offline的应用场景。 比如需要将非常大的结果集拉取出来,存放到其他系统处理,或者需要做大索引的reindex等等。 不要把 scroll 用于实时请求,它主要用于大数据量的场景。例如:将一个索引的内容索引到另一个不同配置的新索引中。

1.7.3 JAVA代码示例

例如滚动查询所有文档:

POST 127.0.0.1:9200/my_index/_search?scroll=1m
{
    "query": {
        "match_all" : {}
    },
    "sort": [
        "_doc"
        ]
    }
}

清除scroll

虽然我们在设置开启scroll时,设置了一个scroll的存活时间,但是如果能够在使用完顺手关闭,可以提早释放资源,降低ES的负担.

DELETE 127.0.0.1:9200/_search/scroll
{
    "scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAdsMqFmVkZTBJalJWUmp5UmI3V0FYc2lQbVEAAAAAAHbDKRZlZGUwSWpSVlJqeVJiN1dBWHNpUG1RAAAAAABpX2sWclBEekhiRVpSRktHWXFudnVaQ3dIQQAAAAAAaV9qFnJQRHpIYkVaUkZLR1lxbnZ1WkN3SEEAAAAAAGlfaRZyUER6SGJFWlJGS0dZcW52dVpDd0hB"
}

JAVA代码示例:com.qianfeng.elasticsearch.query.impl.BaseQueryImpl

@Override
public void scrollQuery(String indexName, String typeName) throws IOException {
    SearchRequest searchRequest = new SearchRequest(indexName);
    searchRequest.types(typeName);
    //初始化scroll
    //值不需要足够长来处理所有数据—它只需要足够长来处理前一批结果。每个滚动请求(带有滚动参数)设置一个新的过期时间。
    final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L)); //设定滚动时间间隔
    searchRequest.scroll(scroll);
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    searchSourceBuilder.query(matchAllQuery());
    searchSourceBuilder.size(5); //设定每次返回多少条数据
    searchRequest.source(searchSourceBuilder);
    log.info("string:" + searchRequest.source());
    SearchResponse searchResponse = null;
    try {
        searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    } catch (IOException e) {
        e.printStackTrace();
    }
    String scrollId = searchResponse.getScrollId();
    SearchHit[] searchHits = searchResponse.getHits().getHits();
    System.out.println("-----首页-----");
    for (SearchHit searchHit : searchHits) {
        System.out.println(searchHit.getSourceAsString());
    }
    //遍历搜索命中的数据,直到没有数据
    while (searchHits != null && searchHits.length > 0) {
        SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
        scrollRequest.scroll(scroll);
        log.info("string:" + scrollRequest.toString());
        try {
            searchResponse = restHighLevelClient.scroll(scrollRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        scrollId = searchResponse.getScrollId();
        searchHits = searchResponse.getHits().getHits();
        if (searchHits != null && searchHits.length > 0) {
            System.out.println("-----下一页-----");
            for (SearchHit searchHit : searchHits) {
                System.out.println(searchHit.getSourceAsString());
            }
        }
?
    }
    
    //清除滚屏
    ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
    clearScrollRequest.addScrollId(scrollId);//也可以选择setScrollIds()将多个scrollId一起使用
    ClearScrollResponse clearScrollResponse = null;
    try {
        clearScrollResponse = restHighLevelClient.clearScroll(clearScrollRequest,RequestOptions.DEFAULT);
    } catch (IOException e) {
        e.printStackTrace();
    }
    boolean succeeded = clearScrollResponse.isSucceeded();
    System.out.println("succeeded:" + succeeded);
}

演示用例:com.qianfeng.elasticsearch.test.document.testIdsQuery

@Test
public void testScrollQuery() throws IOException {
    baseQuery.scrollQuery(indexName,type);
}

演示效果:


源码地址:https://github.com/qfjiaoyan/elasticsearch-examples

相关推荐

好用的云函数!后端低代码接口开发,零基础编写API接口

前言在开发项目过程中,经常需要用到API接口,实现对数据库的CURD等操作。不管你是专业的PHP开发工程师,还是客户端开发工程师,或者是不懂编程但懂得数据库SQL查询,又或者是完全不太懂技术的人,通过...

快速上手:Windows 平台上 cURL 命令的使用方法

在工作流程中,为了快速验证API接口有效性,团队成员经常转向直接执行cURL命令的方法。这种做法不仅节省时间,而且促进了团队效率的提升。对于使用Windows系统的用户来说,这里有一套详细...

使用 Golang net/http 包:基础入门与实战

简介Go的net/http包是构建HTTP服务的核心库,功能强大且易于使用。它提供了基本的HTTP客户端和服务端支持,可以快速构建RESTAPI、Web应用等服务。本文将介绍ne...

#小白接口# 使用云函数,人人都能编写和发布自己的API接口

你只需编写简单的云函数,就可以实现自己的业务逻辑,发布后就可以生成自己的接口给客户端调用。果创云支持对云函数进行在线接口编程,进入开放平台我的接口-在线接口编程,设计一个新接口,设计和配置好接口参...

极度精神分裂:我家没有墙面开关,但我虚拟出来了一系列开关

本内容来源于@什么值得买APP,观点仅代表作者本人|作者:iN在之前和大家说过,在iN的家里是没有墙面开关的。...

window使用curl命令的注意事项 curl命令用法

cmd-使用curl命令的注意点前言最近在cmd中使用curl命令来测试restapi,发现有不少问题,这里记录一下。在cmd中使用curl命令的注意事项json不能由单引号包括起来json...

Linux 系统curl命令使用详解 linuxctrl

curl是一个强大的命令行工具,用于在Linux系统中进行数据传输。它支持多种协议,包括HTTP、HTTPS、FTP等,用于下载或上传数据,执行Web请求等。curl命令的常见用法和解...

Tornado 入门:初学者指南 tornados

Tornado是一个功能强大的PythonWeb框架和异步网络库。它最初是为了处理实时Web服务中的数千个同时连接而开发的。它独特的Web服务器和框架功能组合使其成为开发高性能Web...

PHP Curl的简单使用 php curl formdata

本文写给刚入PHP坑不久的新手们,作为工具文档,方便用时查阅。CURL是一个非常强大的开源库,它支持很多种协议,例如,HTTP、HTTPS、FTP、TELENT等。日常开发中,我们经常会需要用到cur...

Rust 服务器、服务和应用程序:7 Rust 中的服务器端 Web 应用简介

本章涵盖使用Actix提供静态网页...

我给 Apache 顶级项目提了个 Bug apache顶级项目有哪些

这篇文章记录了给Apache顶级项目-分库分表中间件ShardingSphere提交Bug的历程。说实话,这是一次比较曲折的Bug跟踪之旅。10月28日,我们在GitHub上提...

linux文件下载、服务器交互(curl)

基础环境curl命令描述...

curl简单使用 curl sh

1.curl--help#查看关键字2.curl-A“(添加user-agent<name>SendUser-Agent<name>toserver)”...

常用linux命令:curl 常用linux命令大全

//获取网页内容//不加任何选项使用curl时,默认会发送GET请求来获取内容到标准输出$curlhttp://www.baidu.com//输出<!DOCTYPEh...

三十七,Web渗透提高班之hack the box在线靶场注册及入门知识

一.注册hacktheboxHackTheBox是一个在线平台,允许测试您的渗透技能和代码,并与其他类似兴趣的成员交流想法和方法。它包含一些不断更新的挑战,并且模拟真实场景,其风格更倾向于CT...