ElasticSearch两种分页查询

在存在大量数据时,一般我们进行查询都需要进行分页查询。例如:我们指定页码、并指定每页显示多少条数据,然后Elasticsearch返回对应页码的数据。

1、使用from和size来进行分页

在执行查询时,可以指定from(从第几条数据开始查起)和size(每页返回多少条)数据,就可以轻松完成分页。
l from = (page – 1) * size

POST /es_db/_doc/_search
{
  "from": 0,
  "size": 2,
  "query": {
    "match": {
      "address": "广州天河"
    }
  }
}

from size的缺陷

使用from和size方式,查询在1W条数据以内都是OK的,但如果数据比较多的时候,会出现性能问题。Elasticsearch做了一个限制,不允许查询的是10000条以后的数据。

使用from和size方式,在进行大量分页时,每次分页都需要将要查询的数据进行重新排序,这样非常浪费性能。
如果要想深分页查询的话,就用scroll的方式进行分页

2、使用scroll方式进行分页

如果要查询1W条以后的数据,需要使用Elasticsearch中提供的scroll游标来查询。

使用scroll是将要用的数据一次性排序好,然后分批取出。性能要比from + size好得多。使用scroll查询后,排序后的数据会保持一定的时间,后续的分页查询都从该快照取数据即可。

2.1、第一次使用scroll分页查询

此处,我们让排序的数据保持1分钟,所以设置scroll为1m

下面dsl语句的意思是根据name和address字段进行查询,

scroll=1m 的意思是我这个数据帮我缓存1分钟时间(1分钟之后失效),后续查询都是在缓存里面拿 ,

GET /es_db/_search?scroll=1m
{
  "query": {
    "multi_match": {
      "query": "广州长沙张三",
      "fields": [
        "address",
        "name"
      ]
    }
  },
  "size": 1
}

结果:

{
  "_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAJYsWdE9PZWlLaFlRbDY4TU56QnFKVUdnUQ==",
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 5,
      "relation" : "eq"
    },
    "max_score" : 2.2319849,
    "hits" : [
      {
        "_index" : "es_db",
        "_type" : "_doc",
        "_id" : "5",
        "_score" : 2.2319849,
        "_source" : {
          "name" : "小明",
          "sex" : 0,
          "age" : 19,
          "address" : "长沙岳麓山",
          "remark" : "java architect assistant"
        }
      }
    ]
  }
}

“_scroll_id” : “DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAJYsWdE9PZWlLaFlRbDY4TU56QnFKVUdnUQ==”, 这个id值很重要,类似于批次号,你下次要再次进行查询的时候,带上这个_scroll_id之后,ElasticSearch就知道你查询的是哪一批的数据了,
前提是要在你scroll=1m 声明的这1分钟之内去查询,如果超过1分钟再查询就会出现问题了.

2.2、第二次直接使用scroll id进行查询

GET _search/scroll?scroll=1m
{
"scroll_id":"DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAJYsWdE9PZWlLaFlRbDY4TU56QnFKVUdnUQ=="
}

就能查到下一次的数据了

结果:

{
  "_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAH9QWZlgyLVBSYkZUZm03enRpRjZ0aXMzUQ==",
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 5,
      "relation" : "eq"
    },
    "max_score" : 2.2319849,
    "hits" : [
      {
        "_index" : "es_db",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 2.0822616,
        "_source" : {
          "name" : "admin",
          "sex" : 0,
          "age" : 22,
          "address" : "长沙橘子洲头",
          "remark" : "python assistant"
        }
      }
    ]
  }
}

2.3假如说用Java代码操作

如果你用Java代码的话, 你第一次深分页查询的时候,就没有_scroll_id这个参数,然后从返回的参数获取到 _scroll_id 这个,第二次深分页查询的时候就需要带上_scroll_id这个值了,
然后就是需要注意GET _search/scroll?scroll=1m 这种查询的时候设置的scroll=XXXm 的时间,如果超过了这个时间,那么数据就没了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值