李锋镝的博客

  • 首页
  • 时间轴
  • 说说
  • 每日心情
  • Now
  • 系列文章
  • AI工具集
  • 论坛
  • 左邻右舍
    • 左邻右舍
    • 朋友圈
    • 游客中心
  • 留言
    • 留言
    • 走心评论
  • 关于
    • 关于本站
    • 网站地图
    • 网站统计
    • 另一个网站
    • 赞助
  • 星球穿梭
  • 🚇开往
白雪成红
惟坚韧者始能遂其志
  1. 首页
  2. 原创
  3. 正文

SpringBoot整合Elasticsearch游标查询(scroll)

2020年10月16日 约 1,072 字4 分钟 214 0 2
本文最后更新于 2021年5月8日,距今已 1977 天,其中的信息可能已经发生变化,请注意甄别。

游标查询(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 commonStartScroll(Map params, String indexName, String type, String defaultSort,
                                 Map keyMappings,
                                 Map> 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 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 scroll(Map 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 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

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

谢谢~~

参考链接

1
  1. 1https://github.com/lifengdi/searchgithub.com
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
分享到

SpringBoot整合Elasticsearch游标查询(scroll)

也可使用浏览器菜单中的「分享」功能

微信扫一扫分享

标签: ElasticSearch JAVA scroll SpringBoot 搜索
最后更新:2021年5月8日
相关文章
  • ReentrantLock深度解析2025年5月30日
  • Java中的字符和字符串2022年7月18日
  • joda DateTime自定义格式&计算两个日期相差天数2019年8月2日
  • 重构 Controller 终极指南:从臃肿到优雅的 7 大黄金法则 + 实战技巧2025年10月31日
  • 动态线程池框架DynamicTp使用以及架构设计2025年4月29日

李锋镝

既然选择了远方,便只顾风雨兼程。

打赏 点赞
< 上一篇
下一篇 >
1234567891112131415161718192021222324252627282930313233343536373839404142434446474849505152535455575859606162636465666769727476777879808182858687909293949596979899
取消回复
…

文章评论

  • 123456Lv 1

    作为一个初学者没太搞懂,配置文件里面需要修改的参数没有说明,给出的调用接口没有给具体参数和说明看的很糊涂。

    WindowsWindowsChrome 91.0.4472.106Chrome 91.0.4472.106中国中国-河南-郑州
    2021年6月22日
    00 回复
    • 李锋镝Lv 5

      @123456 抱歉哈,以后有时间了会给这块补上的。

      WindowsWindowsChrome 91.0.4472.77Chrome 91.0.4472.77中国中国-北京
      2021年6月30日
      00 回复
  • 当你凝视深渊时,深渊也在凝视你。

    听点儿音乐吧 朋友~
    文章目录
    最新 热点 随机
    最新 热点 随机
    Kratos-plus v1.1.26版本更新说明 我觉得是时候公布我的导航网站了 代码是 AI 写的,生产事故谁背锅? 给主题增加了游客中心功能 祝大家中秋安康 游本昌去世
    给主题增加了游客中心功能游本昌去世关于主题加载速度优化的一点儿小演进我觉得是时候公布我的导航网站了给主题增加了Now、每日心情、年度回顾、岁月同一天、随机漫步等功能WordPress缓存插件WP Fastest Cache、WP Rocket 、FlyingPress对比
    Redis7+&8.X 全新进阶系列(02):Redis Functions 详解——替代Lua脚本的官方轻量化函数方案 写了个日期进度条的小插件 WordPress缓存插件WP Fastest Cache、WP Rocket 、FlyingPress对比 WordPress下一代默认主题Ipsum预览 Java 序列化和反序列化为什么要实现 Serializable 接口? Elasticsearch中的多索引、多类型搜索
    最近评论
    热衷于 发布于 8 小时前(10月06日) AI 喜欢讨好人是一大弊病, 盲目地信任 AI 才是罪魁祸首 我问 AI "你确定吗?&...
    响石潭 发布于 9 小时前(10月06日) 哈哈哈,不错,游客中心,再加上导游功能,就可以按照导游,到博客里面畅游一番
    fairy 发布于 5 天前(10月02日) 很明显,只能处罚人,当然是人背锅。你能罚AI钱吗?能把AI辞退吗?很明显不能。
    彬红茶 发布于 5 天前(10月02日) 很全面哦~国庆快乐
    彬红茶 发布于 5 天前(10月01日) 确实可以加一下这个功能,我最近就改了,评论区加了个等级,游客中心实属无能为力 :78:
    标签聚合
    WordPress 数据库 日常 分布式 MySQL K8s 多线程 JVM Redis JAVA Claude Spring SpringBoot 架构 IDEA AI编程 ElasticSearch AI Theme SQL
    友情链接
    • 老张博客
    • 临窗旋墨
    • 九仞之行
    • 搬砖日记
    • 哥斯拉
    • sssr7844的博客
    • 韩情脉脉
    • 懋和道人
    • Honesty
    • 知向前端
    • 林羽凡
    • 瓦匠个人小站
    • 韩小韩博客
    • 蜗牛工作室
    • 皮皮社
    • lijie blog
    • 志文工作室
    • Mr.Sun的博客
    • Serendipity
    • 若梦博客

    COPYRIGHT © 2016-2026 lifengdi.com. ALL RIGHTS RESERVED.

    lifengdi.com

    Domain age badge for lifengdi.com

    Theme Kratos-plus By Dylan Li

    津ICP备2024022503号-3

    京公网安备11011502039375号