Elasticsearch Search Scroll API 查询全量数据
Elasticsearch 的 Search API 最多只能返回 10000 条检索结果,需要更多检索结果时,就要用到 Search Scroll API 了。
Search Scroll API 就像鼠标的滚轮一样,通过不断地向下滚动直到文档的 ending,从而查询全量结果。
全量文档的查询通常比较耗时,我们需要在请求体中传入过期时间参数 scroll
:
注意到返回结果中有一个字段 _scroll_id
,它记录了保持活动状态的搜索上下文,其中当然也包括当前获取记录的偏移量。
每当准备发起获取新一批次数据的请求时,就要传入上一次请求结果中获取的 scroll_id,告知 es 上一次数据取到哪里了,新一批数据从哪里开始取:
返回结果中还包括字段 _scroll_id
,是取下一批数据用的,以此类推,直到获取全量数据。
初始化
-
创建
SearchRequest
,以及相应的SearchSourceBuilder
. 也可以通过设置 size 控制返回结果数; -
设置滚动查询间隔,时间间隔的设定方法有以下两种:
-
返回的结果中包含一个
scrol id
字段,这个字段干嘛的呢?它记录的是当前保持活动状态的搜索 session 的上下文,在接下来的 search scroll 中将会用到; -
获取第一批检索结果;
获取检索结果
第二步,我们发起的 request 不再是一个 SearchRequest,而是一个 SearchScrollRequest
,SearchScrollRequest 中需要设定的参数包括:
- 上一步骤中返回的 scroll id,这个标识符中保存着 scroll search 的上下文信息,使得检索过程可以从上一次的结束位置继续;
- 新的 scroll 时间间隔;
Elasticsearch 返回具有新滚动标识符的另一批结果。 然后,可以在随后的 SearchScrollRequest 中使用此新的滚动标识符来检索下一批结果,依此类推。 应该循环执行此过程,直到没有更多结果返回为止,这意味着滚动已用尽,并且所有匹配的文档都已被获取。
- 通过设置 scroll id 和 scroll interval 来创建 ScrollSearchRequest;
- 阅读新的滚动 ID,它指向保持活动状态的搜索上下文,在接下来的 Search Scroll 调用中将用到它;
- 获取新一批次的检索结果;
清理上下文
最后,可以使用 Clear Scroll API 删除最后一个滚动标识符,以释放搜索上下文。 尽管滚动过期后会自动清理,但最好的做法是在滚动会话结束后立即进行,释放掉不再占用的资源。
同步请求
异步请求
异步执行搜索滚动请求需要将SearchScrollRequest实例和ActionListener实例传递给异步方法:
异步请求的响应不会立即返回。请求返回时会回调 ActionListener,如果执行成功完成,则使用 onResponse 方法回调ActionListener;如果执行失败,则使用 onFailure 方法回调 ActionListener。
- 执行成功完成时调用,响应作为参数提供;
- 执行失败时调用,异常作为参数提供;
完整示例
滚动搜索的完整示例代码如下:
- 通过发送初始 SearchRequest 初始化搜索上下文;
- 通过在循环中调用 Search Scroll API 来检索所有的搜索结果,直到没有返回任何文档;
- 处理搜索结果;
- 根据上一次返回的 scroll id 和时间间隔创建新的 SearchScrollRequest;
- 滚动搜索结束后,清理上下文;