ES系列十二、ES的scroll Api及分页实例

1.官方api

1.Scroll概念

Version:6.1

英文原文地址:Scroll

当一个搜索请求返回单页结果时,可以使用 scroll API 检索体积大量(甚至全部)结果,这和在传统数据库中使用游标的方式非常相似。

不要把 scroll 用于实时请求,它主要用于大数据量的场景。例如:将一个索引的内容索引到另一个不同配置的新索引中。

2.Client support for scrolling and reindexing(滚动搜索和索引之间的文档重索引)

一些官方支持的客户端提供了一些辅助类,可以协助滚动搜索和索引之间的文档重索引:

Perl

​ 参阅 Search::Elasticsearch::Client::5_0::Bulk 和 Search::Elasticsearch::Client::5_0::Scroll

Python

​ 参阅 elasticsearch.helpers.*

NOTE:从 scroll 请求返回的结果反映了初始搜素请求生成时的索引状态,就像时间快照一样。对文档的更改(索引、更新或者删除)只会影响以后的搜索请求。

回到顶部

3.基本用法

为了使用 scroll ,初始的搜索请求应该在查询字符串中指定 scroll 参数,这个参数会告诉 Elasticsearch 将 “search context” 保存多久。例如:?scroll=1m

复制代码

POST /twitter/_search?scroll=1m
{"size": 100,"query": {"match" : {"title" : "elasticsearch"}}
}

复制代码

上面的请求返回的结果里会包含一个 _scroll_id ,我们需要把这个值传递给 scroll API ,用来取回下一批结果。

  

POST  /_search/scroll 
{"scroll" : "1m", "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==" 
}

(1) GET 或者 POST 都可以

(2) URL 不能包含 index 和 type 名称,原始请求中已经指定了

(3) scroll 参数告诉 Elasticsearch 把搜索上下文再保持一分钟

(4) scroll_id 的值就是上一个请求中返回的 _scroll_id 的值

size 参数允许我们配置每批结果返回的最大命中数。每次调用 scroll API 都会返回下一批结果,直到不再有可以返回的结果,即命中数组为空。

IMPORTANT:初始的搜索请求和每个 scroll 请求都会返回一个新的 _scroll_id ,只有最近的 _scroll_id 是可用的

NOTE:如果请求指定了过滤,就只有初始搜索的响应中包含聚合结果。

NOTE:Scroll 请求对 _doc 排序做了优化。如果要遍历所有的文档,而且不考虑顺序,_doc 是最高效的选项。

复制代码

GET /_search?scroll=1m
{"sort": ["_doc"]
}

复制代码

1.Keeping the search context alive

scroll 参数告诉了 Elasticsearch 应当保持搜索上下文多久。它的值不需要长到能够处理完所有的数据,只要足够处理前一批结果就行了。每个 scroll 请求都会设置一个新的过期时间。

通常,为了优化索引,后台合并进程会把较小的段合并在一起创建出新的更大的段,此时会删除较小的段。这个过程在 scrolling 期间会继续进行,但是一个打开状态的索引上下文可以防止旧段在仍需要使用时被删除。这就解释了 Elasticsearch 为什么能够不考虑对文档的后续修改,而返回初始搜索请求的结果。

TIP:使旧段保持活动状态意味着需要更多的文件句柄。请确保你已将节点配置为拥有足够的可用的文件句柄。详情参阅 File Descriptors

你可以使用 nodes stats API 查看有多少搜索上下文处于开启状态

GET /_nodes/stats/indices/search
GET /_nodes/stats/indices/search

2.Clear scroll API

当超出了 scroll timeout 时,搜索上下文会被自动删除。但是,保持 scrolls 打开是有成本的,当不再使用 scroll 时应当使用 clear-scroll API 进行显式清除。

DELETE /_search/scroll
{"scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ=="
}

可以使用数组传递多个 scroll ID

复制代码

DELETE /_search/scroll
{"scroll_id" : ["DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==","DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAABFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAAAxZrUllkUVlCa1NqNmRMaUhiQlZkMWFBAAAAAAAAAAIWa1JZZFFZQmtTajZkTGlIYkJWZDFhQQAAAAAAAAAFFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAABBZrUllkUVlCa1NqNmRMaUhiQlZkMWFB"]
}

复制代码

使用 _all 参数清除所有的搜索上下文

DELETE /_search/scroll/_all
DELETE /_search/scroll/_all

也可以使用 query string 参数传递 scroll_id ,多个值使用英文逗号分割

DELETE /_search/scroll/DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==,DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAABFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAAAxZrUllkUVlCa1NqNmRMaUhiQlZkMWFBAAAAAAAAAAIWa1JZZFFZQmtTajZkTGlIYkJWZDFhQQAAAAAAAAAFFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAABBZrUllkUVlCa1NqNmRMaUhiQlZkMWFB
DELETE /_search/scroll/DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==,DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAABFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAAAxZrUllkUVlCa1NqNmRMaUhiQlZkMWFBAAAAAAAAAAIWa1JZZFFZQmtTajZkTGlIYkJWZDFhQQAAAAAAAAAFFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAABBZrUllkUVlCa1NqNmRMaUhiQlZkMWFB

3.Sliced Scroll

如果 scroll 查询返回的文档数量过多,可以把它们拆分成多个切片以便独立使用

复制代码

GET /twitter/_search?scroll=1m
{"slice": {"id": 0, "max": 2 },"query": {"match" : {"title" : "elasticsearch"}}
}
GET /twitter/_search?scroll=1m
{"slice": {"id": 1,"max": 2},"query": {"match" : {"title" : "elasticsearch"}}
}

复制代码

(1) 切片的 id

(2) 最大切片数量

上面的栗子,第一个请求返回的是第一个切片(id : 0)的文档,第二个请求返回的是第二个切片的文档。因为我们设置了最大切片数量是 2 ,所以两个请求的结果等价于一次不切片的 scroll 查询结果。默认情况下,先在第一个分片(shard)上做切分,然后使用以下公式:slice(doc) = floorMod(hashCode(doc._uid), max) 在每个 shard 上执行切分。例如,如果 shard 的数量是 2 ,并且用户请求 4 slices ,那么 id 为 0 和 2 的 slice 会被分配给第一个 shard ,id 为 1 和 3 的 slice 会被分配给第二个 shard 。

每个 scroll 是独立的,可以像任何 scroll 请求一样进行并行处理。

NOTE:如果 slices 的数量比 shards 的数量大,第一次调用时,slice filter 的速度会非常慢。它的复杂度时 O(n) ,内存开销等于每个 slice N 位,其中 N 时 shard 中的文档总数。经过几次调用后,筛选器会被缓存,后续的调用会更快。但是仍需要限制并行执行的 sliced 查询的数量,以免内存激增。

为了完全避免此成本,可以使用另一个字段的 doc_values 来进行切片,但用户必须确保该字段具有以下属性:

  • 该字段是数字类型
  • 该字段启用了 doc_values
  • 每个文档应当包含单个值。如果一份文档有指定字段的多个值,则使用第一个值
  • 每个文档的值在创建文档时设置了之后不再更新,这可以确保每个切片获得确定的结果
  • 字段的基数应当很高,这可以确保每个切片获得的文档数量大致相同

复制代码

GET /twitter/_search?scroll=1m
{"slice": {"field": "date","id": 0,"max": 10},"query": {"match" : {"title" : "elasticsearch"}}
}

复制代码

NOTE:默认情况下,每个 scroll 允许的最大切片数量时 1024。你可以更新索引设置中的 index.max_slices_per_scroll 来绕过此限制。

回到顶部

3.实现分页案例

1.实现分页,每页20条数据,第一次请求返回第一页数据

POST /book1/_search?scroll=10m{"size":20
}

复制代码

{"_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAL6FlI4dDZSMjBYUXJpdEpCXzVRVlFzdmcAAAAAAAAC_hZSOHQ2UjIwWFFyaXRKQl81UVZRc3ZnAAAAAAAAAvsWUjh0NlIyMFhRcml0SkJfNVFWUXN2ZwAAAAAAAAL8FlI4dDZSMjBYUXJpdEpCXzVRVlFzdmcAAAAAAAAC_RZSOHQ2UjIwWFFyaXRKQl81UVZRc3Zn","took": 1,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 41,"max_score": 1,"hits": [{"_index": "book1","_type": "english","_id": "_update","_score": 1,"_source": {"scripted_upsert": true,"script": {"id": "my_web_session_summariser","params": {"pageViewEvent": {"url": "foo.com/bar","response": 404,"time": "2014-01-01 12:32"}}},"upsert": {}}},{"_index": "book1","_type": "english","_id": "79","_score": 1,"_source": {"name": "new_name"}}
。。。。
}

复制代码

2.使用scroll_id请求后面的几页的数据,每次返回一页

POST /_search/scroll
{"scroll":"10m","scroll_id" : "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAL6FlI4dDZSMjBYUXJpdEpCXzVRVlFzdmcAAAAAAAAC_hZSOHQ2UjIwWFFyaXRKQl81UVZRc3ZnAAAAAAAAAvsWUjh0NlIyMFhRcml0SkJfNVFWUXN2ZwAAAAAAAAL8FlI4dDZSMjBYUXJpdEpCXzVRVlFzdmcAAAAAAAAC_RZSOHQ2UjIwWFFyaXRKQl81UVZRc3Zn" 
}

最后一页只有一条:

复制代码

{"_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAL6FlI4dDZSMjBYUXJpdEpCXzVRVlFzdmcAAAAAAAAC_hZSOHQ2UjIwWFFyaXRKQl81UVZRc3ZnAAAAAAAAAvsWUjh0NlIyMFhRcml0SkJfNVFWUXN2ZwAAAAAAAAL8FlI4dDZSMjBYUXJpdEpCXzVRVlFzdmcAAAAAAAAC_RZSOHQ2UjIwWFFyaXRKQl81UVZRc3Zn","took": 1,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 41,"max_score": 1,"hits": [{"_index": "book1","_type": "english","_id": "oAmI_mQBbhSmAk-TGrMQ","_score": 1,"_source": {"name": "否sdfdsfds","age": 13,"class": "dsfdsf","addr": "中国"}}]}
}

复制代码

继续执行返回空:

复制代码

{"_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAL6FlI4dDZSMjBYUXJpdEpCXzVRVlFzdmcAAAAAAAAC_hZSOHQ2UjIwWFFyaXRKQl81UVZRc3ZnAAAAAAAAAvsWUjh0NlIyMFhRcml0SkJfNVFWUXN2ZwAAAAAAAAL8FlI4dDZSMjBYUXJpdEpCXzVRVlFzdmcAAAAAAAAC_RZSOHQ2UjIwWFFyaXRKQl81UVZRc3Zn","took": 1,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 41,"max_score": 1,"hits": []}
}

复制代码

3.异常:earchContextMissingException

SearchContextMissingException[No search context found for id [721283]];
原因:scroll设置的时间过短了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/98507.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无法向会话状态服务器发出会话状态请求。请确保 ASP.NET State Service (ASP.NET 状态服务)已启动,并且客户端端口与服务器端口相同

“/”应用程序中的服务器错误。 无法向会话状态服务器发出会话状态请求。请确保 ASP.NET State Service (ASP.NET 状态服务)已启动,并且客户端端口与服务器端口相同。如果服务器位于远程计算机上,请检查 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Se…

【算法设计与分析】— —实现活动安排问题的贪心算法。

🎃欢迎大家前去观看我的算法设计与分析专栏: 算法设计与分析_IT闫的博客-CSDN博客 希望对大家有所帮助! 🎃个人专栏: 🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客 🐳Java…

接口测试常见问题

1.接口测试的流程 测试计划与方案 --> 接口用例设计 --> 接口测试执行 --> 缺陷报告与结果分析 2.接口工具的流程 脚本的设计,数据用例的设计,断言(预期结果的设计),执行 3.测试计划与方案: …

sourceTree无法启动

前几天win10系统自动更新后,sourceTree就无法打开了,双击只是图标闪一下,电脑重启后还是无法打开。找到了网上几种方法进行尝试: 方法一:修改配置信息 在自己的电脑路径下: C:\Users\你的用户名\AppData…

每个.NET开发都应掌握的C#特性(Attribute)知识点

上篇文章讲述了C#反射知识点,本文将介绍C#特性(Attribute)的知识点。C#特性(Attribute)是一种强大的元数据机制,用于为代码元素(如类、方法、属性等)添加信息,以影响它们…

RFID系统简介:优点、应用与发展前景

一、介绍RFID系统 RFID系统全称是Radio Frequency Identification,是一种通过电磁场自动识别标记(Tag或RFID标签)并读取相关数据的技术。与条形码技术相比,RFID系统最大的特点就是可以自动识别、无须接触扫描,并且可以…

gin实现event stream

event stream是属于http的一种通信方式,可以实现服务器主动推送。原理于客户端请求服务器之后一直保持链接,服务端持续返回结果给客户端。相比较于websocket有如下区别: 基于http的通信方式,在各类框架的加持下不需要开发人员自己…

Explainability for Large Language Models: A Survey

本文是LLM系列文章,针对《Explainability for Large Language Models: A Survey》的翻译。 大型语言模型的可解释性:综述 摘要1 引言2 LLM的训练范式3 传统微调范式的解释4 提示范式的解释5 评估的解释6 研究挑战7 结论 摘要 大型语言模型(llm)在自然语言处理方面…

【Leetcode Sheet】Weekly Practice 10

Leetcode Test 123 买卖股票的最佳时机Ⅲ(10.3) 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 **注意:**你不能同时参与多笔交易(你必须在再次购…

简单对比一下 C 与 Go 两种语言

使用一个简单的计数程序将古老的 C 语言与现代 Go 进行比较。 Go 是一种现代编程语言,追溯其历史大部分源自编程语言 C。所以,任何熟悉 C 语言的开发者都可能会觉得 Go 很熟悉。C 程序员使用 Go 编写新程序变得容易,同时避免了 C 编程语言的…

阶段五-Day03-Ajax

一、JavaWeb中路径的说明 1. JavaWeb中的路径 在JavaWeb中, 路径分为相对路劲和绝对路径两种: 相对路径: ./ 表示当前目录 ../ 表示当前文件所在目录的上一级目录 绝对路径: 完整的路径名 2. 在JavaWeb中/的不同意义 /斜杠如果被浏览器解析,得到的是 协议本地ip端口号…

第十二章:泛型(Generic)

1:为什么要有泛型? 泛型:(标签)允许在定义类、接口时候通过一个标识来表示类中某个属性的类型或者是某个方法的返回值及参数类型。这个类型、参数将在使用时(例如:继承或实现这个接口&#xff0…

QML 带框最大化显示方法

1.QML窗口最大化很多会给出如下方法: visibility: "FullScreen" 此方法不好的方面是没有最大化,最小化,关闭按钮 2.通过showMaximized() 方法可以满足我们需求:在onCompleted 方法中执行 实现的效果如下:

QT基础入门——界面布局和常用控件(四)

前言: 所谓 GUI 界面,归根结底,就是一堆组件的叠加。我们创建一个窗口,把按钮放上面,把图标放上面,这样就成了一个界面。在放置时,组件的位置尤其重要。我们必须要指定组件放在哪里&#xff0c…

妙鸭相机功能代码复现

妙鸭相机功能代码复现 妙鸭相机主要实现人脸替换与人脸高清增强修复功能。可通过两种方式实现Roop和Lora模型。 RooP笔记 基础模型:inswapper_128.onnx 人脸分析模型:insightface 高清增强模型:gfpgan 大体流程为通过insightface检测出人脸,替换人脸,使用gfpgan对人…

设计模式——14. 观察者模式

1. 说明 观察者模式(Observer Pattern)是一种行为型设计模式,用于定义对象之间的一对多依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都能够自动收到通知并更新自己的状态,以保持与被观察对象的同步。观察者模式也被称为发布-订阅模式。 观察者模式包含…

改变世界-生成式人工智能

麦肯锡在其《生成人工智能的经济潜力:下一个生产力前沿》中声称,“ChatGPT、GitHub Copilot、Stable Diffusion 等生成式人工智能应用程序以 AlphaGo 没有的方式吸引了世界各地人们的想象力,这要归功于它们广泛的实用性——几乎任何人都可以使…

Java中的Iterator

Java中的Iterator Iterator 是Java中的一个接口,它提供了一种访问集合(如列表、集合等)中元素的标准方式。Iterator 具有一些特点、优点和缺点,下面详细介绍如何使用它以及相关信息。 使用Iterator: 创建Iterator&am…

动态代理初步了解

准备案例 需求 模拟某企业用户管理业务,需包含用户登录,用户删除,用户查询功能,并要统计每个功能的耗时。 分析与实现 定义一个UserService表示用户业务接口,规定必须完成用户登录,用户删除&#xff0c…

2019年[海淀区赛 第2题] 阶乘

题目描述 n的阶乘定义为n!n*(n -1)* (n - 2)* ...* 1。n的双阶乘定义为n!!n*(n -2)* (n -4)* ...* 2或n!!n(n - 2)*(n - 4)* ...* 1取决于n的奇偶性,但是阶乘的增长速度太快了,所以我们现在只想知道n!和n!!末尾的的个数 输入格式 一个正整数n &#xff…