elasticsearch 深度分页问题

熵烬
• 阅读 3687

elasticsearch分页对于用过es的人应该都会使用 ,和数据库的分页类似,如下所示,通过from + size可以对数据进行分页。

{

"from" : 0, 
"size" : 10,
"query" : {
    "term" : { "user" : "dejun" }
}

}

可以查询1-10条记录,不过由于es是分布式的,数据都是分布在多个分片上。
如查询: from = 990 , size = 10 , 分片数为:4 ,那么es是如何 查询的呢? 如下图所示:
elasticsearch 深度分页问题

es会在每个分片获取1000条文档,通过Coordinating Node 汇总各个节点的数据,再通过排序选择前1000个文档返回。
所以当页数越深,查询的节点的数量越大,自然占用的内存也越多,那么我们是不是可以把系统内存查爆? ES为了避免深度分页带来的内存开销,ES默认限定只能查询10000个文档
那么我们做个示范:

POST  /demo/_search
{
  "from" : 0 ,
  "size" : 10001 ,
  "query" : {
            "match_all":{}
}
}

ES会报以下错误:
Result window is too large, from + size must be less than or equal to: [10000] but was [10001]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level parameter.

以上可见,from + size 这种方式不适用于深度分页场景,下面介绍其它两种分页方式…

  • Search After
  • Scroll Api

Search After

可以避免深度分页带来的性能问题,可以实时的获取下一页文档
不支持指定页数,只能向下翻
需要加入排序 sort,并且排序的字段一定要是唯一的
示例:

POST /demo/_search
{
  
   "size": 3, 
  "query": {
    "terms": {
      "txAcctNo": ["11111"
]
    }
  },
  "sort" :{
    "_id" :"desc"
  }
}

ES返回:

{
  "took": 110,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1122,
    "max_score": null,
    "hits": [
      {
        
        "_id": "6140202001021427303890174574324",
        "_score": null,
        "_source": {
        
        },
        "sort": [
          "6140202001021427303890174574324"
        ]
      },
      {
       
        "_id": "6140201912131352403980169574091",
        "_score": null,
        "_source": {
          
        },
        "sort": [
          "6140201912131352403980169574091"
        ]
      },
      {
    
        "_id": "6140201912101038085680169566509",
        "_score": null,
        "_source": {
         
        },
        "sort": [
          "6140201912101038085680169566509"
        ]
      }
    ]
  }
}

每条数据都会有一个sort返回,只需要在下一次查询中,在search_after中加入这个值,如下:

POST /demo/_search
{
  
   "size": 3, 
  "query": {
    "terms": {
      "txAcctNo": ["11111"
]
    }
  },
  "sort" :{
    "_id" :"desc"
    
  },
  "search_after" :[
          "6140202001171118484170182578541"
        ]
}

以上即是search_after的用法,其实很简单,那么为什么search_afterr适合深度分页呢,来看一下原理:

假设size:10 ,查询10000-10010,search_after会通过唯一排序的值定位,每个节点只会查10条数据,避免了内存开销过大的问题

elasticsearch 深度分页问题

点赞
收藏
评论区
推荐文章
菜鸟阿都 菜鸟阿都
4年前
pageHelper一对多分页解决方案
前言   pageHelper是一款优秀的Mybatis分页插件,在项目中可以非常便利的使用,使开发效率得到很大的提升,但不支持一对多结果映射的分页查询,所以在平时的使用时,对于一对多分页会出现分页错误,这篇文章主要对pageHelper分页错误进行重现以及提出解决方案。分析    mybatis进行一对多查询时,映射文件(mapper.xml
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
ElasticSearch深度分页详解
1前言ElasticSearch是一个实时的分布式搜索与分析引擎,常用于大量非结构化数据的存储和快速检索场景,具有很强的扩展性。纵使其有诸多优点,在搜索领域远超关系型数据库,但依然存在与关系型数据库同样的深度分页问题,本文就此问题做一个实践性
Wesley13 Wesley13
3年前
Java代码解决ElasticSearch的Result window is too large
调用ElasticSearch做分页查询时报错:QueryPhaseExecutionException\Resultwindowistoolarge,fromsizemustbelessthanorequalto:\10000\butwas\666000\.Seethescrollapifor
Stella981 Stella981
3年前
SpringBoot学习之路:05.Spring Boot集成pagehelper分页插件
      前面说了SpringBoot集成持久层框架Mybatis的过程,和使用mybatis进行对数据库进行CRUD的操作,然而当对多数据进行查询时就需要进行分页了,分页技术分为客户端分页和服务器端分页(数据库分页),客户端分页是前端的数据插件对返回的数据集进行分页(bootstruptable、quitable等),客户端分页会对数据库和客
Easter79 Easter79
3年前
SpringBoot学习之路:05.Spring Boot集成pagehelper分页插件
      前面说了SpringBoot集成持久层框架Mybatis的过程,和使用mybatis进行对数据库进行CRUD的操作,然而当对多数据进行查询时就需要进行分页了,分页技术分为客户端分页和服务器端分页(数据库分页),客户端分页是前端的数据插件对返回的数据集进行分页(bootstruptable、quitable等),客户端分页会对数据库和客
Stella981 Stella981
3年前
JFinal各种场景(PC、APP、微信小程序等)分页方案
JFinal专题之分页解决方案【课程介绍】 详细介绍数据库分页原理,自己动手封装前端分页组件,然后介绍第三方的js分页组件,集成laypage插件,了解各种分页模式,不管是跳转分页,数据库分页、前端分页、滚动加载分页、ajax数据分页、APP移动端分页、微信小程序分页等【课程目标】 掌握数据库分页原理,熟练使用JFinal操作数据库分页查
Stella981 Stella981
3年前
Elasticsearch分页解决方案
一、命令的方式做分页1、常见的分页方式:fromsizeelasticsearch默认采用的分页方式是fromsize的形式,但是在深度分页的情况下,这种使用方式的效率是非常低的,比如from5000,size10,es需要在各个分片上匹配排序并得到5000\10条有效数据,然后在结果集中取最后10条数据返回。除了会遇到效率上的问题
Stella981 Stella981
3年前
ELK学习笔记之ElasticSearch的索引详解
0x00ElasticSearch的索引和MySQL的索引方式对比Elasticsearch是通过Lucene的倒排索引技术实现比关系型数据库更快的过滤。特别是它对多条件的过滤支持非常好,比如年龄在18和30之间,性别为女性这样的组合查询。倒排索引很多地方都有介绍,但是其比关系型
Elasticsearch Mapping类型修改
背景通常数据库进行分库分表后,目前比较常规的作法,是通过将数据异构到Elasticsearch来提供分页列表查询服务;在创建Elasticsearch索引时,基本都是会参考目前的业务需求、关系数据库中的类型以及对数据的相关规划来定义相关字段mapping的