es深度分页原因概念及处理方法

概述

当使用es分页查询的时候,如果查询的数据太靠后了,就会产生深度分页问题。

假设es有3个节点,node1,node2,node3
查询 limti 50000,50
假设请求的是node1,此时会在每个节点上抓出 50050条数据,然后在node1汇总排序,取出50条数据。此时就发生了深度分页问题。es在2.0之后有个配置参数max_result_window限制了深度分页最大是10000。

search_after查询

查询的是实时的数据,但是每次查询需要带上上一次查询的最后一个sort值。并且需要文档中有一个字段保存唯一值,一般就用uuid来填充了。

所以在查询的时候需要一页一页的查询下去,因为需要拿到上一次的sort值,如果一次性查询 limit 20000,20还是不行的,需要从第一页开始查询下去。

请求demo
文档中的uid属性是唯一的

GET /student/student/_search
{
  "query":{
    "match_all": {}
  },
  "size":2,
  "sort":[
    {
      "uid": "desc"
    }
  ]
}

结果demo,结果集中有sort字段,下一次的search_after查询需要带上此次最后一条记录的sort的值

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 6,
    "max_score" : null,
    "hits" : [
      {
        "_index" : "student",
        "_type" : "student",
        "_id" : "6",
        "_score" : null,
        "_source" : {
          "uid" : 1006,
          "name" : "dehua",
          "age" : 27,
          "class" : "3-1"
        },
        "sort" : [
          1006
        ]
      },
      {
        "_index" : "student",
        "_type" : "student",
        "_id" : "5",
        "_score" : null,
        "_source" : {
          "uid" : 1005,
          "name" : "fucheng",
          "age" : 23,
          "class" : "2-3"
        },
        "sort" : [
          1005
        ]
      }
    ]
  }
}

下一次的search_after查询

GET /student/student/_search
{
  "query":{
    "match_all": {}
  },
  "size":2,
  "search_after":[1005],
  "sort":[
    {
      "uid": "desc"
    }
  ]
}

游标查询

适合大数据量的一次性查询
类似mysql的游标查询,在查询的时候生成一个快照,然后不断的分批从快照中获取数据,可以设置这个快照的过期时间。此时文档数据被修改是不会同步给快照中的数据的。

请求demo

GET /student/student/_search
{
  "query":{
    "match_all": {}
  },
  "size":2,
  "search_after":[1005],
  "sort":[
    {
      "uid": "desc"
    }
  ]
}

第一次响应的数据中有_scroll_id字段,后面的scroll查询都要带上这个字段

{
  "_scroll_id" : "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAC0YFmllUjV1QTIyU25XMHBTck1XNHpFWUEAAAAAAAAtGRZpZVI1dUEyMlNuVzBwU3JNVzR6RVlBAAAAAAAALRsWaWVSNXVBMjJTblcwcFNyTVc0ekVZQQAAAAAAAC0aFmllUjV1QTIyU25XMHBTck1XNHpFWUEAAAAAAAAtHBZpZVI1dUEyMlNuVzBwU3JNVzR6RVlB",
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 6,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "student",
        "_type" : "student",
        "_id" : "5",
        "_score" : 1.0,
        "_source" : {
          "name" : "fucheng",
          "age" : 23,
          "class" : "2-3"
        }
      },
      {
        "_index" : "student",
        "_type" : "student",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "name" : "xiaoming",
          "age" : 25,
          "class" : "2-1"
        }
      }
    ]
  }
}

后面的连续查询
当结果集为空的时候代表查询完毕

GET /_search/scroll
{
  "scroll":"5m",
  "scroll_id":"DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAC0YFmllUjV1QTIyU25XMHBTck1XNHpFWUEAAAAAAAAtGRZpZVI1dUEyMlNuVzBwU3JNVzR6RVlBAAAAAAAALRsWaWVSNXVBMjJTblcwcFNyTVc0ekVZQQAAAAAAAC0aFmllUjV1QTIyU25XMHBTck1XNHpFWUEAAAAAAAAtHBZpZVI1dUEyMlNuVzBwU3JNVzR6RVlB"
}

这个index中一共有6条数据,游标查询每次查询2条
es深度分页原因概念及处理方法_第1张图片
es深度分页原因概念及处理方法_第2张图片
es深度分页原因概念及处理方法_第3张图片

你可能感兴趣的:(es,elasticsearch,数据库,大数据)