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": ,
"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

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

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

DELETE /_search/scroll/DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==,DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAABFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAAAxZrUllkUVlCa1NqNmRMaUhiQlZkMWFBAAAAAAAAAAIWa1JZZFFZQmtTajZkTGlIYkJWZDFhQQAAAAAAAAAFFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAABBZrUllkUVlCa1NqNmRMaUhiQlZkMWFB

3.Sliced Scroll

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

GET /twitter/_search?scroll=1m
{
"slice": {
"id": ,
"max":
},
"query": {
"match" : {
"title" : "elasticsearch"
}
}
}
GET /twitter/_search?scroll=1m
{
"slice": {
"id": ,
"max":
},
"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": ,
"max":
},
"query": {
"match" : {
"title" : "elasticsearch"
}
}
}

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

3.实现分页案例

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

POST /book1/_search?scroll=10m

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

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

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

最后一页只有一条:

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

继续执行返回空:

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

3.异常:earchContextMissingException

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

ES系列十二、ES的scroll Api及分页实例的更多相关文章

  1. ES系列十、ES常用查询API

    1.term查询 { "query": { "term": { "title": "crime" } } } 1.1.指 ...

  2. Web 前端开发精华文章推荐(jQuery、HTML5、CSS3)【系列十二】

    2012年12月12日,[<Web 前端开发人员和设计师必读文章>系列十二]和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HT ...

  3. SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据

    原文:SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Se ...

  4. Alamofire源码解读系列(十二)之请求(Request)

    本篇是Alamofire中的请求抽象层的讲解 前言 在Alamofire中,围绕着Request,设计了很多额外的特性,这也恰恰表明,Request是所有请求的基础部分和发起点.这无疑给我们一个Req ...

  5. struts2官方 中文教程 系列十二:控制标签

    介绍 struts2有一些控制语句的标签,本教程中我们将讨论如何使用 if 和iterator 标签.更多的控制标签可以参见 tags reference. 到此我们新建一个struts2 web 项 ...

  6. 爬虫系列(十二) selenium的基本使用

    一.selenium 简介 随着网络技术的发展,目前大部分网站都采用动态加载技术,常见的有 JavaScript 动态渲染和 Ajax 动态加载 对于爬取这些网站,一般有两种思路: 分析 Ajax 请 ...

  7. ES系列十五、ES常用Java Client API

    一.简介 1.先看ES的架构图 二.ES支持的客户端连接方式 1.REST API http请求,例如,浏览器请求get方法:利用Postman等工具发起REST请求:java 发起httpClien ...

  8. ES系列十六、集群配置和维护管理

    一.修改配置文件 1.节点配置 1.vim elasticsearch.yml # ======================== Elasticsearch Configuration ===== ...

  9. Alamofire源码解读系列(十二)之时间轴(Timeline)

    本篇带来Alamofire中关于Timeline的一些思路 前言 Timeline翻译后的意思是时间轴,可以表示一个事件从开始到结束的时间节点.时间轴的概念能够应用在很多地方,比如说微博的主页就是一个 ...

随机推荐

  1. 博主自传——蒟蒻的OI之路

    博主来自河北石家庄市第二中学,现在读高二,主攻信息学竞赛(其实并没有学习其他学科竞赛). NOIP中人品大爆发,使劲挤进河北省一等奖队伍,侥幸留在竞赛团队中(差点就淘汰出局啦). 关于我的ID,YOU ...

  2. 一种使用emwin库函数导致hardfault的情况

    @2018-08-27 使用函数 WM_SendMessageNoPara(hWin_MainTask, WM_INIT_DIALOG),调试至此处进入hardfault,经查是由于hWin_Main ...

  3. P3507 GRA-The Minima Game

    题目大意: 给出N个正整数,AB两个人轮流取数,A先取.每次可以取任意多个数,直到N个数都被取走.每次获得的得分为取的数中的最小值,A和B的策略都是尽可能使得自己的得分减去对手的得分更大.在这样的情况 ...

  4. A1019. General Palindromic Number

    A number that will be the same when it is written forwards or backwards is known as a Palindromic Nu ...

  5. A1061. Dating

    Sherlock Holmes received a note with some strange strings: "Let's date! 3485djDkxh4hhGE 2984akD ...

  6. [luoguU42591][小T的面试题]

    luoguU42591 题意: n个不超过n的正整数中,其中有一个数出现了两次,其余的数都只出现了一次, 求这个出现两次的数. 思路: 这个题的亮点在于内存限制1MB.明显不能再用数组储存了,肯定是用 ...

  7. C# winform C/S WebBrowser 微信第三方登录

    网上很多的资料都是B/S结构的,这里是基于C# C/S 结构的微信第三方授权登录 一.准备知识 1 http Get和Post方法.做第三方授权登录,获取信息基本上都是用get和post方法,做之前需 ...

  8. Django model中的 class Meta 详解

    通过一个内嵌类 "class Meta" 给你的 model 定义元数据, 类似下面这样: class Foo(models.Model): bar = models.CharFi ...

  9. max,min,Zip函数(十一)

    zip函数,拉链,传两个有序的参数,将他们一一对应为元祖形式 max,min比较默认比较一个元素,处理的是可迭代对象,相当于for循环取出每个元素进行比较,注意:不同类型之间不可比较 #!/usr/b ...

  10. P3594 [POI2015]WIL-Wilcze doły

    P3594 [POI2015]WIL-Wilcze doły 题目描述 给定一个长度为n的序列,你有一次机会选中一段连续的长度不超过d的区间,将里面所有数字全部修改为0.请找到最长的一段连续区间,使得 ...