SpringBoot整合Elasticsearch游标查询(scroll)
游标查询(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)的更多相关文章
- elasticsearch 布尔过滤器 游标查询 Scroll
组合过滤器 | Elasticsearch: 权威指南 | Elastic https://www.elastic.co/guide/cn/elasticsearch/guide/current/co ...
- SpringBoot整合ElasticSearch实现多版本的兼容
前言 在上一篇学习SpringBoot中,整合了Mybatis.Druid和PageHelper并实现了多数据源的操作.本篇主要是介绍和使用目前最火的搜索引擎ElastiSearch,并和Spring ...
- ElasticSearch(2)---SpringBoot整合ElasticSearch
SpringBoot整合ElasticSearch 一.基于spring-boot-starter-data-elasticsearch整合 开发环境:springboot版本:2.0.1,elast ...
- springboot整合elasticsearch入门例子
springboot整合elasticsearch入门例子 https://blog.csdn.net/tianyaleixiaowu/article/details/72833940 Elastic ...
- SpringBoot整合Elasticsearch详细步骤以及代码示例(附源码)
准备工作 环境准备 JAVA版本 java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1.8.0_121 ...
- Springboot整合Elasticsearch报错availableProcessors is already set to [4], rejecting [4]
Springboot整合Elasticsearch报错 今天使用SpringBoot整合Elasticsearch时候,相关的配置完成后,启动项目就报错了. nested exception is j ...
- 😊SpringBoot 整合 Elasticsearch (超详细).md
SpringBoot 整合 Elasticsearch (超详细) 注意: 1.环境搭建 安装es Elasticsearch 6.4.3 下载链接 为了方便,环境使用Windows 配置 解压后配置 ...
- Springboot整合elasticsearch以及接口开发
Springboot整合elasticsearch以及接口开发 搭建elasticsearch集群 搭建过程略(我这里用的是elasticsearch5.5.2版本) 写入测试数据 新建索引book( ...
- Springboot整合ElasticSearch进行简单的测试及用Kibana进行查看
一.前言 搜索引擎还是在电商项目.百度.还有技术博客中广泛应用,使用最多的还是ElasticSearch,Solr在大数据量下检索性能不如ElasticSearch.今天和大家一起搭建一下,小编是看完 ...
随机推荐
- ZK集群源码解读
1.1. 集群模式 1.1.1. 数据同步总流程 1.1.1.1. OBSERVING 1.1.1.2. FOLLOWING 1.1.1.3. LEADING 1.1.2. 领导选举 1.1.2. ...
- Django 中 a href标签 使用方法 跳转页面(Django四)
上次我已经用Django启动了一个登录模板页面 具体过程见:Django启动我的第一个模板页面 但问题是我们只能通过监听的端口访问这一个页面,不能通过页面的一些连接跳转到其他页面如下,我们不能点击注册 ...
- [剑指Offer]65-不用加减乘除做加法
题目 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. 题解 用位运算模拟加法的三步: 无进位加法:异或运算. 进位:与运算再左移一位. 直到进位为0结束. 代码 pub ...
- 解决ExcelReport导出Excel报Number of rules must not exceed 3错误的问题
报错信息: Number of rules must not exceed 3 [ArgumentException: Number of rules must not exceed 3] NPOI. ...
- 原生post请求
ajax: function(opt) { opt = opt || {}; opt.method = opt.method.toUpperCase() || 'POST'; opt.url = op ...
- MySQL必知必会(1-12章)
第一章:了解SQL 数据库基础:(概念) 数据库软件: DBMS(数据库管理系统) 数据库: 通过DBMS创建和操纵的容器: 保存有组织的数据的容器-->通常是一个文件或者一组文件: 表: 某种 ...
- Android如何使用注解进行代码检查
原文首发于微信公众号:躬行之(jzman-blog),欢迎关注交流! Android Studio 内置了代码检查工具 Lint,可在菜单栏选择 Analyze > Inspect Code 执 ...
- 转载:python的format格式化输出
https://www.cnblogs.com/chunlaipiupiupiu/p/7978669.html python中format函数 ---恢复内容开始--- python中format ...
- 微信小程序-简介
微信小程序定位 1. 不需要下载安装即可使用 2. 用户用完即走,不用关系是否安装太多应用 3. 应用无处不在,随时可用 # 不要安装可使用是个伪命题,因为小程序的安装包小于1M,下载安装到使用的过程 ...
- Vue编写的页面部署到springboot网站项目中出现页面加载不全问题
问题描述: 在用Vue脚手架 编写出一个页面之后, 部署到后台项目中, 因为做的是一个页面 按理来说 怎么都能够在服务器上运行 , 我也在自己的node环境测试 , 在同学的springboot上运行 ...