游标查询(scroll)简介

scroll 查询 可以用来对 Elasticsearch 有效地执行大批量的文档查询,而又不用付出深度分页那种代价。

游标查询会取某个时间点的快照数据。 查询初始化之后索引上的任何变化会被它忽略。 它通过保存旧的数据文件来实现这个特性,结果就像保留初始化时的索引 视图 一样。

启用游标查询可以通过在查询的时候设置参数 scroll 的值为我们期望的游标查询的过期时间。 游标查询的过期时间会在每次做查询的时候刷新,所以这个时间只需要足够处理当前批的结果就可以了,而不是处理查询结果的所有文档的所需时间。 这个过期时间的参数很重要,因为保持这个游标查询窗口需要消耗资源,所以我们期望如果不再需要维护这种资源就该早点儿释放掉。 设置这个超时能够让 Elasticsearch 在稍后空闲的时候自动释放这部分资源。

GET /old_index/_search?scroll=1m
{
"query": { "match_all": {}},
"sort" : ["_doc"],
"size": 1000
}

scroll=1m:保持游标查询窗口一分钟。

返回结果示例:

{
"_scroll_id": "cXVlcnlUaGVuRmV0Y2g7NTsxMDk5NDpkUmpiR2FjOFNhNnlCM1ZDMWpWYnRROzEwOTk1OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MTA5OTM6ZFJqYkdhYzhTYTZ5QjNWQzFqVmJ0UTsxMTE5MDpBVUtwN2lxc1FLZV8yRGVjWlI2QUVBOzEwOTk2OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MDs=",
"took": 10,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 2633253,
"max_score": 1.0,
"hits": [
{
"_index": "old_index",
"_type": "old_index_type",
"_id": "1",
"_score": 1.0,
"_source": {
...
}
}
]
}
}

这个查询的返回结果包括一个字段 _scroll_id, 它是一个base64编码的长字符串 。 现在我们能传递字段 _scroll_id_search/scroll 查询接口获取下一批结果:

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

注意:需要再次设置游标查询过期时间为一分钟。

这个游标查询返回下一批结果。

另外尽管我们指定字段 size 的值为1000,但是我们有可能取到超过这个值数量的文档。 当查询的时候, 字段 size 作用于单个分片,所以每个批次实际返回的文档数量最大为 size * number_of_primary_shards

注意:游标查询每次返回一个新字段 _scroll_id。每次我们做下一次游标查询, 我们必须把前一次查询返回的字段_scroll_id 传递进去。 当没有更多的结果返回的时候,我们就处理完所有匹配的文档了。

整合

新增以下三个方法:

/**
* 游标查询
* @param params 查询入参
* @param indexName 索引名称
* @param type 索引类型
* @param defaultSort 默认排序
* @param keyMappings 字段映射
* @param keyMappingsMap 索引对应字段映射
* @param scrollTimeInMillis 游标开启的时间
* @return Page
*/
protected Page<Map> commonStartScroll(Map<String, String> params, String indexName, String type, String defaultSort,
Map<Key, FieldDefinition> keyMappings,
Map<String, Map<Key, FieldDefinition>> keyMappingsMap, long scrollTimeInMillis) {
SearchQuery searchQuery = buildSearchQuery(params, indexName, type, defaultSort, keyMappings, keyMappingsMap);
return elasticsearchTemplate.startScroll(scrollTimeInMillis, searchQuery, Map.class);
} /**
* 游标查询
* @param scrollId 游标ID
* @param scrollTimeInMillis 游标开启的时间
* @return Page
*/
protected Page<Map> commonContinueScroll(String scrollId, long scrollTimeInMillis) {
return elasticsearchTemplate.continueScroll(scrollId, scrollTimeInMillis, Map.class);
} /**
* 根据游标ID清除游标(提早释放资源,降低ES的负担)
* @param scrollId 游标ID
*/
protected void clearScroll(String scrollId) {
elasticsearchTemplate.clearScroll(scrollId);
}

StoreSearchService中增加游标查询方法以及清除游标方法:

/**
* 游标查询
* @param params 查询条件
* @return page
*/
public Page<Map> scroll(Map<String, String> params) {
IndexConfig config = indexEntity.getConfigByDocCode(DOC_CODE); // 如果请求参数包含游标ID,则说明执行翻页操作,否则认为开启新的游标查询
String scrollId = params.getOrDefault(SCROLL_ID, null);
if (StringUtils.isNotBlank(scrollId)) {
return commonContinueScroll(params.get(scrollId), config.getScrollTimeInMillis());
}
return commonStartScroll(params, config.getIndexName(), config.getType(), DEFAULT_SORT,
keyMappings, keyMappingsMap, config.getScrollTimeInMillis());
}
public void clearScroll(String scrollId) {
super.clearScroll(scrollId);
}

对外暴露接口:

@PostMapping("/scroll")
public ResponseResult scroll(@RequestBody Map<String, String> params) { return ResponseResult.success(storeSearchService.scroll(params));
} @GetMapping("/scroll/clear/{scrollId}")
public ResponseResult clearScroll(@PathVariable String scrollId) {
storeSearchService.clearScroll(scrollId);
return ResponseResult.success(null);
}

游标查询分为开启和继续两个步骤,接口/scroll中根据_scrollId判断为开启游标查询还是继续游标查询。

若条件允许的话,尽量将游标查询及时关闭,以释放ES集群的资源,降低负担。

源码

Git项目地址:https://github.com/lifengdi/search

如果觉得有帮助的话,请帮忙点赞、点星小小的支持一下~

谢谢~~

原文链接:https://www.lifengdi.com/archives/article/2119

SpringBoot整合Elasticsearch游标查询(scroll)的更多相关文章

  1. elasticsearch 布尔过滤器 游标查询 Scroll

    组合过滤器 | Elasticsearch: 权威指南 | Elastic https://www.elastic.co/guide/cn/elasticsearch/guide/current/co ...

  2. SpringBoot整合ElasticSearch实现多版本的兼容

    前言 在上一篇学习SpringBoot中,整合了Mybatis.Druid和PageHelper并实现了多数据源的操作.本篇主要是介绍和使用目前最火的搜索引擎ElastiSearch,并和Spring ...

  3. ElasticSearch(2)---SpringBoot整合ElasticSearch

    SpringBoot整合ElasticSearch 一.基于spring-boot-starter-data-elasticsearch整合 开发环境:springboot版本:2.0.1,elast ...

  4. springboot整合elasticsearch入门例子

    springboot整合elasticsearch入门例子 https://blog.csdn.net/tianyaleixiaowu/article/details/72833940 Elastic ...

  5. SpringBoot整合Elasticsearch详细步骤以及代码示例(附源码)

    准备工作 环境准备 JAVA版本 java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1.8.0_121 ...

  6. Springboot整合Elasticsearch报错availableProcessors is already set to [4], rejecting [4]

    Springboot整合Elasticsearch报错 今天使用SpringBoot整合Elasticsearch时候,相关的配置完成后,启动项目就报错了. nested exception is j ...

  7. 😊SpringBoot 整合 Elasticsearch (超详细).md

    SpringBoot 整合 Elasticsearch (超详细) 注意: 1.环境搭建 安装es Elasticsearch 6.4.3 下载链接 为了方便,环境使用Windows 配置 解压后配置 ...

  8. Springboot整合elasticsearch以及接口开发

    Springboot整合elasticsearch以及接口开发 搭建elasticsearch集群 搭建过程略(我这里用的是elasticsearch5.5.2版本) 写入测试数据 新建索引book( ...

  9. Springboot整合ElasticSearch进行简单的测试及用Kibana进行查看

    一.前言 搜索引擎还是在电商项目.百度.还有技术博客中广泛应用,使用最多的还是ElasticSearch,Solr在大数据量下检索性能不如ElasticSearch.今天和大家一起搭建一下,小编是看完 ...

随机推荐

  1. jQuery的那些事儿

    jQuery概述 j-JavaScript+Query就是查询js的库,把js中的DOM操作做了封装,实现快速查询使用其中的功能. 优化了DOM操作.事件处理.动画设计和Ajax交互 学习jQuery ...

  2. iTextSharp生成PDF文件

    这是一篇简单的教程,所以只涉及一些iTextSharp生成pdf的简单应用,详细教程请搜索iTextSharp进入官网看官方文档(英文版). iTextSharp官方文档:https://itextp ...

  3. linux系统漏洞扫描工具lynis

    lynis 是一款运行在 Unix/Linux 平台上的基于主机的.开源的安全审计软件.Lynis是针对Unix/Linux的安全检查工具,可以发现潜在的安全威胁.这个工具覆盖可疑文件监测.漏洞.恶意 ...

  4. 突然挂了!Redis缓存都在内存中,这下完了!

    我是Redis,一个叫Antirez的男人把我带到了这个世界上. “快醒醒!快醒醒!”,隐隐约约,我听到有人在叫我. 慢慢睁开眼睛,原来旁边是MySQL大哥. “我怎么睡着了?” “嗨,你刚才是不是出 ...

  5. SpringBoot-01-快速入门

    SpringBoot 1. 快速入门 什么是Spring 轻量级的Java开源开发框架 为了解决企业级应用开发的复杂性而创建的,简化开发 Spring是如何简化Java开发的 ​ 为了降低Java开发 ...

  6. Vue 登录/登出以及JWT认证

    1. 后端代码概览 server/router/index.js 请求 router.get('/getUserInfo', function (req, res, next) { // 登录请求 r ...

  7. netty---sync,await

    LOG.info("*************************WINDOWS系统*********************************"); //设置事件处理 ...

  8. 20行代码实现,使用Tarjan算法求解强连通分量

    今天是算法数据结构专题的第36篇文章,我们一起来继续聊聊强连通分量分解的算法. 在上一篇文章当中我们分享了强连通分量分解的一个经典算法Kosaraju算法,它的核心原理是通过将图翻转,以及两次递归来实 ...

  9. 朴素版和堆优化版dijkstra和朴素版prim算法比较

    1.dijkstra 时间复杂度:O(n^2) n次迭代,每次找到距离集合S最短的点 每次迭代要用找到的点t来更新其他点到S的最短距离. #include<iostream> #inclu ...

  10. Java11-ZGC

    Java 11包含一个全新的垃圾收集器--ZGC,它由Oracle开发,承诺在数TB的堆上具有非常低的暂停时间. 在本文中,我们将介绍开发新GC的动机,技术概述以及由ZGC开启的一些可能性. 那么为什 ...