【分页问题】elasticsearch 深分页问题以及解决方法

news/2024/7/7 21:45:25

本文主要参考:

1、https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html
2、《Elasticsearch权威指南》
 
好,下面上货。
 
首先介绍一下,什么是深分页问题。
当使用elasticsearch进行分页查询的时候我们使用的语法是这样的:
POST xytest/sutdent/_search
{
  "from": 0,
  "size": 2
}
 
这样的查询在10000-50000条数据(1000到5000页)以内的时候还是可以的,但是如果数据过多的话,就会出现深分页问题。这个问题和elasticsearch的内部原理有关。比如,现在要取第5001页的数据,在分页的时候,elasticsearch需要首先在每一个节点上取出50020的数据,然后和每一个节点的所有数据进行排序,取出排序后在50010到50020的数据,然后返回。这样随着数据量的增大,每次分页时排序的开销会越来越大。
 
为了解决上面的问题,elasticsearch提出了一个scroll滚动的方式,这个滚动的方式原理就是通过每次查询后,返回一个scroll_id。根据这个scroll_id 进行下一页的查询。可以把这个scroll_id理解为通常关系型数据库中的游标。但是,这种scroll方式的缺点是不能够进行反复查询,也就是说,只能进行下一页,不能进行上一页。
 
经过分析,如果数据达到了50000条以上,那么用户基本上是不会考虑每条都去看的,用户需要的是最后对数据分析处理后的结果。而如果小于50000条的时候我们可以使用from size的方式进行分页的查询。那么这种方式存在是为了什么情景呢。应该是为了分批次的检索所有数据。
 
下面,介绍一下如何使用这种scroll的方式进行分页查询。
我们的环境里一共有6条数据,我们每次取出4条。
 
1、首先取出前4条,并且得到scroll_id(这里的3m代表的是持续滚动时间,如果过了3分钟,还没有查询下一页,那么这个scroll_id就会失效)。
POST /xytest/sutdent/_search?scroll=3m
{
    "size": 4
}
 
再次查询下一页,注意,这里查询时不需要指定index,只需要指定scroll_id和本次的持续滚动时间。
POST /_search/scroll
{
    "scroll" : "3m",
    "scroll_id":"DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAueFjZoLTd3UEptUXFXR2Z6Nm5iZ3FqalEAAAAAAAALnBY2aC03d1BKbVFxV0dmejZuYmdxampRAAAAAAAAC58WNmgtN3dQSm1RcVdHZno2bmJncWpqUQAAAAAAAAudFjZoLTd3UEptUXFXR2Z6Nm5iZ3FqalEAAAAAAAALoBY2aC03d1BKbVFxV0dmejZuYmdxampR"
}
 
发现这次只有两条数据,我们再次根据返回的scroll_id查询
POST /_search/scroll
{
    "scroll" : "3m",
    "scroll_id":"DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAueFjZoLTd3UEptUXFXR2Z6Nm5iZ3FqalEAAAAAAAALnBY2aC03d1BKbVFxV0dmejZuYmdxampRAAAAAAAAC58WNmgtN3dQSm1RcVdHZno2bmJncWpqUQAAAAAAAAudFjZoLTd3UEptUXFXR2Z6Nm5iZ3FqalEAAAAAAAALoBY2aC03d1BKbVFxV0dmejZuYmdxampR"
}
 
已经没有数据了,说明已经滚动到最后了。
这个时候我们可以删除这个scroll_id。
使用如下方法:
DELETE /_search/scroll/DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAueFjZoLTd3UEptUXFXR2Z6Nm5iZ3FqalEAAAAAAAALnBY2aC03d1BKbVFxV0dmejZuYmdxampRAAAAAAAAC58WNmgtN3dQSm1RcVdHZno2bmJncWpqUQAAAAAAAAudFjZoLTd3UEptUXFXR2Z6Nm5iZ3FqalEAAAAAAAALoBY2aC03d1BKbVFxV0dmejZuYmdxampR
 
 
也可以删除所有scroll_id:
DELETE /_search/scroll/_all

http://www.niftyadmin.cn/n/3532710.html

相关文章

10 UI线程阻塞及其优化

1、button1移动30次的小动画: Ui_thread01Activity.java: public class Ui_thread01Activity extends Activity {/** Called when the activity is first created. */Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState)…

dubbo-zookeeper

说到分布式,大家可能很快就能想到阿里巴巴的dubbo,zoookeeper集群,目前spring-cloud也是比较热门的,spring-cloud是基于spinrg-boot之上进行协作的, 接下来就先说一下使用dubbo远程接口调用和zookeeper集群 1、首先创建一个maven工…

棋盘问题总结

我们在研究问题时经常能碰到这一类为题:在某个棋盘上有一种棋子,问最多放下几个棋子。或者有一堆棋子,问你移去最少的棋子数目,使得剩下来的棋子两两不攻击。 先看下面这道题 问题 E: P1035 时间限制: 1 Sec 内存限制: 128 MB提交…

javascript的rsa加密和python的rsa解密

先说下目前测试情况:javascript加密后的数据,python无法完成解密,我估计是两者的加密解密方法不同 1、看了这篇文章:http://blog.nsfocus.net/python-js-encrypts-post-form-data-rsa-algorithm/ ,然后网上搜索了下&am…

上传excel文件存到服务器并且读取sheet

// 文件目录String fileNameuploadFile.getFileItem().getName();//文件名String uploadDir SystemProperties.getProperty("upload.dir");//获取系统时间SimpleDateFormat simpleDateFormat new SimpleDateFormat("yyyyMMdd"); Date date new Date()…

Ionic2如何下拉刷新和上拉加载

2019独角兽企业重金招聘Python工程师标准>>> http://www.cnblogs.com/hujinshui/p/6404798.html 转载于:https://my.oschina.net/yizhichao/blog/1476698

轻轻松松教你写日志-超级简单

近期在做一个项目。涉及到非常多的服务,一步步调试相当麻烦,要在自己电脑上公布非常多服务,又要所有开启。非常费时间。出现故障,怎么解决最快呢?直接写日志,一步定位哪里出了错。Log4Net库是一个帮助程序猿…

IOS Object和javaScript相互调用

在IOS开发中有时会用到Object和javaScript相互调用,详细过程例如以下: 1. Object中运行javascript代码,这个比較简单,苹果提供了非常好的方法 - (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script 2. javas…