ElasticSearch的scroll滚动查询以及在Springboot中的使用

什么是es中的scroll?

scroll即滚动查询,我们知道,es中在进行普通的查询时,默认只会查询出来10条数据。我们通过设置es中的size可以将最终的查询结果从10增加到10000,那么问题来了,当我们需要查询的数据大于10000条怎么办?这时有两种方式解决:深度分页滚动查询。优先使用滚动查询,因为深度分页越往后查性能越低,极其耗费内存和CPU。

深度分页

分页即使用from和size,如下:

{
    "query": {
        "match_all": {}
    },
    "from": 9990,
    "size": 20
}

像这样就能够获取到9990-10010的20条数据了,但是这样每次都需要将前面的9990条数据查询出来,然后再向下继续寻找后面的20条,最终就会导致搜索很深,即深度分页,性能就会受到极大影响,因此这种方式不推荐使用。

滚动查询

滚动查询,和关系型数据库中的游标有点类似,因此也叫游标查询。也相当于一个快照,它是es中提供的一种查询大数据量的方式。

在dsl语句中,完成一个scroll查询分为两步:

第一步:带有查询条件,根据条件查询。

GET search_account/_search?scroll=1m
{
  "size":1000, 
  "query": {
    "term": {
      "type": {
        "value": "生活"
      }
    }
  }
}

这是一个简单的term查询哈,这个查询条件比较简单,相当于一个示意,关键点两个:

① scroll表示这是一个scroll滚动查询;

② scroll=1m表示查询的结果数据在es服务器中过期时间为1min。

该查询返回的结果如下:

可以看到,返回结果中有一个_scroll_id字段,该字段其实就相当于一个书签,在我们之后的查询中需要带着这个书签,就可以一直往后根据设置的size大小获取数据(前提是在设置的过期时间之内)。

第二步:获取的scroll_id作为查询条件往后查询数据。

GET /_search/scroll/
{
  "scroll":"1m",
  "scroll_id":"DnF1ZXJ5VGhlbkZldGNoBgAAAABtmn3QFnJNSEk2S2FBVENTQ21JR0dtVXZEbFEAAAAAaePcNhZaOGZsVmdlaFRNdVgyYS04dlNhTDJBAAAAAG2afdEWck1ISTZLYUFUQ1NDbUlHR21VdkRsUQAAAABplHFdFkpvME9pZEd1U0pXdVlSc29CYXFkZHcAAAAAamCmqhZVNXRmNFhlNFN5NjZwMHZraE5ndEV3AAAAAGnj3DcWWjhmbFZnZWhUTXVYMmEtOHZTYUwyQQ=="
}

将获取的scroll_id作为条件继续查询即可,不需要再指定索引和类型。因为scroll_id具有唯一性,在过期时间内,之后查询的scroll_id是不变的。

滚动查询在Springboot中的使用

以上说明的是在dsl语句中如何使用scroll,但是既然涉及到大数据量,在dsl中完成就不太可能了,一般都是通过代码的方式进行滚动查询。这里说明一下es中的scroll查询在Springboot中的使用:

环境准备:springboot项目,es依赖,restHighLevelClient客户端配置。(具体配置这里就不赘述了,咱们直接上手)

需求描述:现已经获取了大批账号的uid(20万以上的数据),需要根据这些账号的uid去es中查询账号所属的分类信息。

代码:

public String redoAccountTypeByScroll(List<String> uidList) {
        List<List<RedoAccountTypeVO>> resultList=new ArrayList<>();

        //构造es查询条件。
        SearchRequest searchRequest = new SearchRequest("search_account");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        sourceBuilder.query(QueryBuilders.termsQuery("uid",uidList))
                //设置最多一次能够取出10000条数据,从第10001条数据开始,将开启滚动查询。
                .size(10000)
                .fetchSource(new String[]{"uid","type"},null);
        searchRequest.source(sourceBuilder);
        //设置scroll超时时间(10min)。
        Scroll scroll=new Scroll(TimeValue.timeValueMinutes(10L));
        //放入滚动查询对象。
        searchRequest.scroll(scroll);
        SearchResponse response = restHighLevelClient.search(searchRequest);

        //TODO:这里可以解析response对象,获取前10000条数据,封装实体类对象(属性为uid和type),并构成集合accountTypeVOList。我这里假设已经解析response对象完成,得到了accountTypeVOList集合。
        resultList.add(accountTypeVOList);

        //记录滚动id。
        String scrollId=response.getScrollId();
        //滚动查询部分,将从第10001条数据开始取。
        SearchHit[] scrollHits = response.getHits().getHits();
        while (ObjectUtil.isNotNull(scrollHits) && scrollHits.length > 0 ) {
            //构造滚动查询条件
            SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId);
            searchScrollRequest.scroll(scroll);
            //响应必须是上面的响应对象,需要对上一层进行覆盖。
            response = restHighLevelClient.scroll(searchScrollRequest);
            scrollId = response.getScrollId();
            scrollHits=response.getHits().getHits();

            //TODO:同上面一样,在这个位置可以对滚动查询到的从10001条数据开始的数据进行处理(封装实体类),构成集合accountTypeVOList(假设我已经构成了集合)。
            resultList.add(accountTypeVOList);
        }

        //TODO:在循环结束后可以遍历resultList这个大集合,来实现我们自己的需求,我这里是获取账号分类(由于我这里需要调用其它项目完成账号分类的获取,代码就不再贴了,感觉冗余。读者需要明白这里是实现自己的业务需求)。
       

        //数据获取完毕后需要清楚滚动,否则影响下次查询。
        ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
        clearScrollRequest.addScrollId(scrollId);
        ClearScrollResponse clearScrollResponse = restHighLevelClient.clearScroll(clearScrollRequest);
        //清除滚动是否成功
        boolean isSuccess = clearScrollResponse.isSucceeded();
        log.info("=====================>清楚滚动scroll是否成功:{}",isSuccess);
        return "==================>账号分类获取完毕~";
    }

总结:

① 滚动查询是建立在普通查询基础上的。

② 需要注意的是:滚动查询相当于快照,如果在使用scroll进行滚动查询期间有增删改的操作,那么查询结果是获取不到最新的数据的。

③ 深度分页和滚动查询优先使用滚动查询,性能更优,CPU资源耗费更少。

希望对你有所帮助!

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
前言 第1章 Elasticsearch入门 1 1.1 Elasticsearch是什么 1 1.1.1 Elasticsearch的历史 2 1.1.2 相关产品 3 1.2 全文搜索 3 1.2.1 Lucene介绍 4 1.2.2 Lucene倒排索引 4 1.3 基础知识 6 1.3.1 Elasticsearch术语及概念 6 1.3.2 JSON介绍 10 1.4 安装配置 12 1.4.1 安装Java 12 1.4.2 安装Elasticsearch 12 1.4.3 配置 13 1.4.4 运行 15 1.4.5 停止 17 1.4.6 作为服务 17 1.4.7 版本升级 19 1.5 对外接口 21 1.5.1 API约定 22 1.5 .2 REST介绍 25 1.5.3 Head插件安装 26 1.5.4 创建库 27 1.5.5 插入数据 28 1.5.6 修改文档 28 1.5.7 查询文档 29 1.5.8 删除文档 29 1.5.9 删除库 30 1.6 Java接口 30 1.6.1 Java接口说明 30 1.6.2 创建索引文档 33 1.6.3 增加文档 34 1.6.4 修改文档 35 1.6.5 查询文档 35 1.6.6 删除文档 35 1.7 小结 36 第2章 索引 37 2.1 索引管理 37 2.1.1 创建索引 37 2.1.2 删除索引 39 2.1.3 获取索引 39 2.1.4 打开/关闭索引 40 2.2 索引映射管理 41 2.2.1 增加映射 41 2.2.2 获取映射 44 2.2.3 获取字段映射 45 2.2.4 判断类型是否存在 46 2.3 索引别名 46 2.4 索引配置 51 2.4.1 更新索引配置 51 2.4.2 获取配置 52 2.4.3 索引分析 52 2.4.4 索引模板 54 2.4.5 复制配置 55 2.4.6 重建索引 56 2.5 索引监控 60 2.5.1 索引统计 60 2.5.2 索引分片 62 2.5.3 索引恢复 63 2.5.4 索引分片存储 64 2.6 状态管理 64 2.6.1 清除缓存 64 2.6.2 索引刷新 64 2.6.3 冲洗 65 2.6.4 合并索引 65 2.7 文档管理 66 2.7.1 增加文档 66 2.7.2 更新删除文档 69 2.7.3 查询文档 73 2.7.4 多文档操作 76 2.7.5 索引词频率 80 2.7.6 查询更新接口 83 2.8 小结 87 第3章 映射 88 3.1 概念 88 3.2 字段数据类型 90 3.2.1 核心数据类型 91 3.2.2 复杂数据类型 96 3.2.3 地理数据类型 100 3.2.4 专门数据类型 106 3.3 元字段 108 3.3.1 _all字段 109 3.3.2 _field_names字段 109 3.3.3 _id字段 110 3.3.4 _index字段 110 3.3.5 _meta字段 111 3.3.6 _parent字段 111 3.3.7 _routing字段 112 3.3.8 _source字段 114 3.3.9 _type字段 115 3.3.10 _uid字段 115 3.4 映射参数 116 3.4.1 analyzer参数 116 3.4.2 boost参数 118 3.4.3 coerce参数 119 3.4.4 copy_to参数 120 3.4.5 doc_values参数 121 3.4.6 dynamic参数 122 3.4.7 enabled参数 122 3.4.8 fielddata参数 123 3.4.9 format参数 126 3.4.10 geohash参数 128 3.4.11 geohash_precision参数 129 3.4.12 geohash_prefix参数 130 3.4.13 ignore_above参数 131 3.4.14 ignore_malformed参数 131 3.4.15 include_in_all参数 132 3.4.16 index参数 133 3.4.17 index_options参数 133 3.4.18 lat_lon参数 134 3.4.19 fields参数 135 3.4.20 norms参数 136 3.4.21 null_value参数 137 3.4.22 position_increment_gap参数 137 3.4.23 precision_step参数 138 3.4.24 properties参数 138 3.4.25 search_analyzer参数 139 3.4.26 similarity参数 140 3.4.27 store参数 141 3.4.28 term_vector参数 141 3.5 动态映射 142 3.5.1 概念 142 3.5.2 _default_映射 143 3.5.3 动态字段映射 143 3.5.4 动态模板 145 3.5.5 重写默认模板 148 3.6 小结 148 第4章 搜索 149 4.1 深入搜索 149 4.1.1 搜索方式 149 4.1.2 重新评分 153 4.1.3 滚动查询请求 155 4.1.4 隐藏内容查询 158 4.1.5 搜索相关函数 161 4.1.6 搜索模板 164 4.2 查询DSL 167 4.2.1 查询和过滤的区别 167 4.2.2 全文搜索 168 4.2.3 字段查询 179 4.2.4 复合查询 183 4.2.5 连接查询 188 4.2.6 地理查询 190 4.2.7 跨度查询 197 4.2.8 高亮显示 200 4.3 简化查询 203 4.4 小结 206 第5章 聚合 207 5.1 聚合的分类 207 5.2 度量聚合 209 5.2.1 平均值聚合 209 5.2.2 基数聚合 211 5.2.3 最大值聚合 213 5.2.4 最小值聚合 214 5.2.5 和聚合 214 5.2.6 值计数聚合 215 5.2.7 统计聚合 215 5.2.8 百分比聚合 215 5.2.9 百分比分级聚合 216 5.2.10 最高命排行聚合 217 5.2.11 脚本度量聚合 217 5.2.12 地理边界聚合 221 5.2.13 地理重心聚合 222 5.3 分组聚合 223 5.3.1 子聚合 224 5.3.2 直方图聚合 226 5.3.3 日期直方图聚合 230 5.3.4 时间范围聚合 233 5.3.5 范围聚合 234 5.3.6 过滤聚合 235 5.3.7 多重过滤聚合 236 5.3.8 空值聚合 238 5.3.9 嵌套聚合 239 5.3.10 采样聚合 240 5.3.11 重要索引词聚合 242 5.3.12 索引词聚合 245 5.3.13 总体聚合 251 5.3.14 地理点距离聚合 251 5.3.15 地理散列网格聚合 253 5.3.16 IPv4范围聚合 255 5.4 管道聚合 257 5.4.1 平均分组聚合 259 5.4.2 移动平均聚合 261 5.4.3 总和分组聚合 262 5.4.4 总和累计聚合 262 5.4.5 最大分组聚合 264 5.4.6 最小分组聚合 265 5.4.7 统计分组聚合 266 5.4.8 百分位分组聚合 268 5.4.9 差值聚合 269 5.4.10 分组脚本聚合 273 5.4.11 串行差分聚合 275 5.4.12 分组选择器聚合 276 5.5 小结 277 第6章 集群管理 278 6.1 集群节点监控 278 6.1.1 集群健康值 278 6.1.2 集群状态 279 6.1.3 集群统计 280 6.1.4 集群任务管理 280 6.1.5 待定集群任务 281 6.1.6 节点信息 281 6.1.7 节点统计 282 6.2 集群分片迁移 283 6.3 集群节点配置 284 6.3.1 主节点 285 6.3.2 数据节点 286 6.3.3 客户端节点 286 6.3.4 部落节点 287 6.4 节点发现 287 6.4.1 主节点选举 288 6.4.2 故障检测 288 6.5 集群平衡配置 289 6.5.1 分片分配设置 289 6.5.2 基于磁盘的配置 290 6.5.3 分片智能分配 291 6.5.4 分片配置过滤 292 6.5.5 其他集群配置 293 6.6 小结 293 第7章 索引分词器 294 7.1 分词器的概念 294 7.2 文分词器 298 7.3 插件 300 7.3.1 插件管理 301 7.3.2 插件安装 301 7.3.3 插件清单 302 7.4 小结 304 第8章 高级配置 305 8.1 网络相关配置 305 8.1.1 本地网关配置 305 8.1.2 HTTP配置 306 8.1.3 网络配置 307 8.1.4 传输配置 308 8.2 脚本配置 310 8.2.1 脚本使用 311 8.2.2 脚本配置 313 8.3 快照和恢复配置 318 8.4 线程池配置 324 8.5 索引配置 326 8.5.1 缓存配置 326 8.5.2 索引碎片分配 329 8.5.3 合并 332 8.5.4 相似模块 332 8.5.5 响应慢日志监控 333 8.5.6 存储 335 8.5.7 事务日志 336 8.6 小结 337 第9章 告警、监控和权限管理 338 9.1 告警 338 9.1.1 安装 338 9.1.2 结构 339 9.1.3 示例 352 9.1.4 告警输出配置 354 9.1.5 告警管理 355 9.2 监控 356 9.2.1 安装 356 9.2.2 配置 357 9.3 权限管理 360 9.3.1 工作原理 361 9.3.2 用户认证 361 9.3.3 角色管理 366 9.3.4 综合示例 368 9.4 小结 369 第10章 ELK应用 370 10.1 Logstash 370 10.1.1 配置 371 10.1.2 插件管理 374 10.2 Kibana配置 377 10.2.1 Discover 379 10.2.2 Visualize 381 10.2.3 Dashboard 383 10.2.4 Settings 386 10.3 综合示例 387 10.4 小结 390 附录 Elasticsearch 5.0的特性与改进 391
Spring Boot项目使用Elasticsearch,需要在pom.xml文件添加相关依赖。以下是一个使用Spring BootElasticsearch的简单示例: 1.添加依赖 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> ``` 2.配置Elasticsearch属性 在application.properties文件添加Elasticsearch的配置属性,例如: ```properties spring.data.elasticsearch.cluster-name=my-application spring.data.elasticsearch.cluster-nodes=localhost:9300 ``` 3.定义实体类 在Spring Boot应用程序,可以使用Spring Data Elasticsearch来定义Elasticsearch实体类。例如: ```java @Document(indexName="blog",type="article") public class Article { @Id private String id; private String title; private String content; // getters and setters } ``` 4.定义Elasticsearch存储库 定义一个Elasticsearch存储库接口,例如: ```java public interface ArticleRepository extends ElasticsearchRepository<Article, String> { List<Article> findByTitle(String title); } ``` 5.在服务使用Elasticsearch存储库 在服务注入Elasticsearch存储库,并使用它执行Elasticsearch操作,例如: ```java @Service public class ArticleService { @Autowired private ArticleRepository articleRepository; public List<Article> search(String title) { return articleRepository.findByTitle(title); } public void save(Article article) { articleRepository.save(article); } } ``` 这是一个简单的示例,演示了如何在Spring Boot应用程序使用Elasticsearch。你可以使用这个示例作为起点,根据自己的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值