前面的文章提到过es默认的from+size的分页方式返回的结果数据集不能超过1万点,超过之后返回的数据越多性能就越低。
这是因为es要计算相似度排名,需要排序整个整个结果集,假设我们有一个index它有5个shard,现在要读取1000到1010之间的这10条数据,es内部会在每个shard上读取1010条数据,然后返回给计算节点,这里有朋友可能问为啥不是10条数据而是1010条呢?这是因为某个shard上的10条数据,可能还没有另一个shard上top10之后的数据相似度高,所以必须全部返回,然后在计算节点上,重新对5050条数据进行全局排序,最后在选取top 10出来,这里面排序是非常耗时的,所以这个数量其实是指数级增长的,到后面分页数量越多性能就越下降的厉害,而且大量的数据排序会占用jvm的内存,很有可能就OOM了,这也是为什么es默认不允许读取超过1万条数据的原因。
那么问题来了,我就是想要深度的分页数据应该怎么办? es里面提供了两种方式来读取深度分页的数据:
(1)离线的读取深度分页数据的Scroll方法
(2)能够用于实时和高并发场景的searchAfter方法(5.x之后)
Scroll方式在前面的文章提到过,它通过一次查询请求后维护一个索引快照的search context,然后每次再去批量的读取数据,效率比较高。在5.x之后,还可以通过slice分片来实现并行导出。
它的缺点就是维护一个search context需要占用很多资源,而且在快照建立之后数据变化如删除和更新操作是不能被感知到的,所以不能够用于实时和高并发的场景。
searchAfter的方式通过维护一个实时游标来避免scroll的缺点,它可以用于实时请求和高并发场景。
它的缺点是不能够随机跳转分页,只能是一页一页的向后翻,并且需要至少指定一个唯一不重复字段来排序。
此外还有一个与scorll的不同之处是searchAfter的读取数据的顺序会受索引的更新和删除影响而scroll不会,因为scroll读取的是不可变的快照。
下面来看下如何使用searchAfter:
我们先查询一页数据:
````js
GET twitter/_search
{
"size": 10,
"query": {
"match" : {
"title" : "elasticsearch"
}
},
"sort": [
{"date": "asc"},
{"_id": "desc"}
]
}
````
注意,上面用了两个字段来排序,第一个是业务字段可能不唯一,但是第二个id字段一定唯一不重复的。只有这样才能确保searchAfter的翻页顺序读取。
另外searchAfter的from字段一定要设置成0,不然会有问题。
第一个请求发出之后,我们需要获取第一个请求里面最后一条的数据的date和id,然后把这个信息传送到下一个批次,依次类推直到把所有的数据处理完。
如下第二个请求的查询体:
````
GET twitter/_search
{
"size": 10,
"query": {
"match" : {
"title" : "elasticsearch"
}
},
"search_after": [1463538857, "654323"],
"sort": [
{"date": "asc"},
{"_id": "desc"}
]
}
````
总结:
本篇文章介绍了如何在es里面使用深度分页的功能,并对比了scroll和searchAfter的优缺点及不同之处,了解这些知识之后,我们就可以在适合的场景下正确的选择最优的处理方式。
有什么问题可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。 技术债不能欠,健康债更不能欠, 求道之路,与君同行。
分享到:
相关推荐
es深度分页: 主要讨论了es的几种分页机制: 1、分页概述 2、浅分页 3、scroll深分页 4、search_after分页
方法如果传总页数了,es就不用查询总页数,直接通过开始位置到结束位置取数即可
Java API整合ES实现深分页,高亮等操作
Spring Boot结合Jest实现对ElasticSearch的...PageController中的搜索方法里面是全套的,分词,分页,高亮等都包含,数据格式个es-head中创建索引的索引在压缩包里面都有 还是不懂的可以看我的博文里面有详细的介绍
es查询类封装
java 集成elasticsearch分页查询,不用更改elasticsearch配置支持分页查询并且全数据查询出来
聚合查询分页测试termsAgg.size(2147483647); //指定最大统计显示多少行步骤1:全量聚合,size设置为: 2147483647。 ES5.X/6.X版本设置为2147483647 ,它等于2^31-1,请看该地方代码
java连接elasticsearch实现全文检索,并且高亮显示结果,实现分页。项目基于elasticsearch5.6.1可根据自己实际情况调整版本。最近项目需要所以学习了一下,项目很简单可以根据你的实际情况更改接口。我本地的搜索是...
(狂神)ElasticSearch快速入门笔记,ElasticSearch基本操作以及爬虫(Java-ES仿京东实战),包含了小狂神讲的东西,特别适合新手学习,笔记保存下来可以多看看。好记性不如烂笔头哦~,ElasticSearch,简称es,es是一个...
es 提供了3种方式来解决分页与遍历的问题: – from/size – scroll – search_afterForm/Size 最常见的分页方案 – from指明开始位置 – size 指明获取总数 scroll 遍历文档集的 api,以快照的方式来避免深度分页的...
十分钟学会使用 Elasticsearch 优雅搭建自己的搜索系统。 什么是elasticsearch Elasticsearch 是一个开源的高度可扩展的全文搜索和分析引擎,拥有查询近实时的超强性能。 大名鼎鼎的Lucene 搜索引擎被广泛用于搜索...
elasticsearch elasticsearch-6.2.2 elasticsearch-6.2.2.zip 下载
一般来说我们开发Elasticsearch会选择使用集成springboot,在网上找的springboot集成elasticsearch文章几乎都是extends ElasticsearchRepository的方式来实现。但是新版本ElasticsearchRepository里的方法基本上已经...
Elasticsearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。根据DB-Engines的排名显示,Elastic...
elasticsearch java使用手册包含最基本的es使用方法。
全文搜索引擎ElasticSearch介绍与使用
spring-data-elasticsearch中文使用文档,spring-data-elasticsearch、elasticsearch、ES、ElasticSearch、ES中文教程
如果我们安装不成功,我们可以直接下载 Elasticsearch-SQL 插件的压缩包,然后解压,完成之后重命名文件夹为 sql ,放到 ES 的安装路径的 plugins目录中,例如:..\elasticsearch-6.4.0\plugins\sql。
docker run --name elasticsearch7.16.3 -p 127.0.0.1:9200:9200 -p 127.0.0.1:9300:9300 -e "discovery.type=single-node" -v /Users/xingyue/Home/xingyue/学习/工程化/es/elasticsearch.yml:/usr/share/elastic...
Logstash 和 Beats 有助于收集、聚合和丰富您的数据并将其存储在 Elasticsearch 中。Kibana 使您能够以交互方式探索、可视化和分享对数据的见解,并管理和监控堆栈。 Elasticsearch 为所有类型的数据提供近乎实时的...