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
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及分页实例的更多相关文章
- ES系列十、ES常用查询API
1.term查询 { "query": { "term": { "title": "crime" } } } 1.1.指 ...
- Web 前端开发精华文章推荐(jQuery、HTML5、CSS3)【系列十二】
2012年12月12日,[<Web 前端开发人员和设计师必读文章>系列十二]和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HT ...
- SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据
原文:SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Se ...
- Alamofire源码解读系列(十二)之请求(Request)
本篇是Alamofire中的请求抽象层的讲解 前言 在Alamofire中,围绕着Request,设计了很多额外的特性,这也恰恰表明,Request是所有请求的基础部分和发起点.这无疑给我们一个Req ...
- struts2官方 中文教程 系列十二:控制标签
介绍 struts2有一些控制语句的标签,本教程中我们将讨论如何使用 if 和iterator 标签.更多的控制标签可以参见 tags reference. 到此我们新建一个struts2 web 项 ...
- 爬虫系列(十二) selenium的基本使用
一.selenium 简介 随着网络技术的发展,目前大部分网站都采用动态加载技术,常见的有 JavaScript 动态渲染和 Ajax 动态加载 对于爬取这些网站,一般有两种思路: 分析 Ajax 请 ...
- ES系列十五、ES常用Java Client API
一.简介 1.先看ES的架构图 二.ES支持的客户端连接方式 1.REST API http请求,例如,浏览器请求get方法:利用Postman等工具发起REST请求:java 发起httpClien ...
- ES系列十六、集群配置和维护管理
一.修改配置文件 1.节点配置 1.vim elasticsearch.yml # ======================== Elasticsearch Configuration ===== ...
- Alamofire源码解读系列(十二)之时间轴(Timeline)
本篇带来Alamofire中关于Timeline的一些思路 前言 Timeline翻译后的意思是时间轴,可以表示一个事件从开始到结束的时间节点.时间轴的概念能够应用在很多地方,比如说微博的主页就是一个 ...
随机推荐
- 【BZOJ2245】[SDOI2011]工作安排(费用流)
[BZOJ2245][SDOI2011]工作安排(费用流) 题面 BZOJ 洛谷 题解 裸的费用流吧. 不需要拆点,只需要连边就好了,保证了\(W_j<W_{j+1}\). #include&l ...
- mysql数据库几种引擎
· InnoDB:用于事务处理应用程序,具有众多特性,包括ACID事务支持.(提供行级锁) · BDB:可替代InnoDB的事务引擎,支持COMMIT.ROLLBACK和其他事务特性. · Memor ...
- linux ssh keys
1. 原理: SSH 密钥对总是成双出现的,一把公钥,一把私钥.公钥可以自由的放在您所需要连接的 SSH 服务器上,而私钥必须稳妥的保管好. 所谓"公钥登录",原理很简单,就是用户 ...
- 【POJ3662】Telephone Lines dij + 二分答案
题目大意:给定一个 N 个顶点,M 条边的无向图,求一条从 1 号节点到 N 号节点之间的路径,使得第 K+1 大的边权最小,若 1 与 N 不连通,输出 -1. 最小化最大值一类的问题,采用二分答案 ...
- (转)同一服务器部署多个tomcat时的端口号修改详情
背景:在同一个服务器上部署工程,总会遇到tomcat端口占用的情况,所有有必要分清楚各个端口的作用,和需要更改的端口. 同一服务器部署多个tomcat时,存在端口号冲突的问题,所以需要修改tomcat ...
- get方式传值中文乱码
问题描述: 本机可以,服务器乱码: 解决方案: 我采用了第三条,改server.xml配置 方法一: get方式提交的参数编码,只支持iso8859-1编码.因此,如果里面有中文.在后台就需要转换编码 ...
- 错误:分析 EntityName 时出错 web配置
会发生这种错误的环境:ASP.NET 或 XML情况:一个原本运行正常的C#页面,因为SQL的密码更改后一直出现“分析 EntityName 时出错”错误,验证过web.config的SQL Conn ...
- ElasticSearch入门介绍一
ElasticSearch 关于es的几个概念: 集群:多个运行es节点可以组成一个集群,它们拥有相同的cluster.name. 节点:运行es的实例 索引:相当于数据库database,一个集群可 ...
- ajax上传文件及进度显示
之前在博文:原生ajax写法就提及过ajax2.0与1.0的差别是多了FormData和利用FormData文件上传(当然还有跨域,但不是本文的重点). 那么具体怎么样实现ajax上传文件呢? 一般来 ...
- springboot websocket 一篇足够了
什么是WebSocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 … 为什么要实现握手监控管理 如果说,连接随意创建,不管的话,会存在错误,broken pipe 表面看单纯报 ...