深分页Scroll

本文详细介绍了Elasticsearch中from+size查询限制及Scroll API的工作原理。from+size查询效率低,因涉及全量数据排序。而Scroll API通过保存搜索上下文,分批获取数据,适合大量数据分页。Java实现示例展示了如何使用Scroll API进行分页查询,包括初始化、滚动查询和清除上下文的过程。
摘要由CSDN通过智能技术生成

ES对from + size是有限制的,from和size二者之和不能超过1W

原理:

  • from+size在ES查询数据的方式:

    • 第一步现将用户指定的关键进行分词。

    • 第二步将词汇去分词库中进行检索,得到多个文档的id。

    • 第三步去各个分片中去拉取指定的数据。耗时较长。

    • 第四步将数据根据score进行排序。耗时较长。

    • 第五步根据from的值,将查询到的数据舍弃一部分。

    • 第六步返回结果。

    • 解释:相当于拉取全部数据,按score进行排序,只取前十个,所以效率低

  • scroll+size在ES查询数据的方式:

    • 第一步现将用户指定的关键进行分词。

    • 第二步将词汇去分词库中进行检索,得到多个文档的id。

    • 第三步将文档的id存放在一个ES的上下文中。

    • 第四步根据你指定的size的个数去ES中检索指定个数的数据,拿完数据的文档id,会从上下文中移除。

    • 第五步如果需要下一页数据,直接去ES的上下文中,找后续内容。

    • 第六步循环第四步和第五步

    • 解释:相当于把文档id存在es的一个域中,根据指定的size拿取数据,拿完的移除,下一页拿剩下的

Scroll查询方式,不适合做实时的查询

因为Scroll查询,如果地第一次拿到两个,剩下全在上下文中,这时,改变数据库,上下文中存的数据还是旧的,拿不到最新的

 

# 执行scroll查询,返回第一页数据,并且将文档id信息存放在ES上下文中,指定生存时间1m
POST /sms-logs-index/sms-logs-type/_search?scroll=1m
{
  "query": {
    "match_all": {}
  },
  "size": 2,
  "sort": [					# 排序
    {
      "fee": {
        "order": "desc"
      }
    }
  ]
}

# 根据scroll查询下一页数据
POST /_search/scroll
{
  "scroll_id": "<根据第一步得到的scorll_id去指定>",
  "scroll": "<scorll信息的生存时间>"
}


# 删除scroll在ES上下文中的数据
DELETE /_search/scroll/scroll_id

 

// Java实现scroll分页
@Test
public void scrollQuery() throws IOException {
    //1. 创建SearchRequest
    SearchRequest request = new SearchRequest(index);
    request.types(type);

    //2. 指定scroll信息
    request.scroll(TimeValue.timeValueMinutes(1L));

    //3. 指定查询条件
    SearchSourceBuilder builder = new SearchSourceBuilder();
    builder.size(2);
    builder.sort("fee", SortOrder.DESC);
    builder.query(QueryBuilders.matchAllQuery());
    
    request.source(builder);

    //4. 获取返回结果scrollId,source
    SearchResponse resp = client.search(request, RequestOptions.DEFAULT);

    String scrollId = resp.getScrollId();
    System.out.println("----------首页---------");
    for (SearchHit hit : resp.getHits().getHits()) {
        System.out.println(hit.getSourceAsMap());
    }


    while(true) {
        //5. 循环 - 创建SearchScrollRequest
        SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);

        //6. 指定scrollId的生存时间
        scrollRequest.scroll(TimeValue.timeValueMinutes(1L));

        //7. 执行查询获取返回结果
        SearchResponse scrollResp = client.scroll(scrollRequest, RequestOptions.DEFAULT);

        //8. 判断是否查询到了数据,输出
        SearchHit[] hits = scrollResp.getHits().getHits();
        if(hits != null && hits.length > 0) {
            System.out.println("----------下一页---------");
            for (SearchHit hit : hits) {
                System.out.println(hit.getSourceAsMap());
            }
        }else{
            //9. 判断没有查询到数据-退出循环
            System.out.println("----------结束---------");
            break;
        }
    }


    //10. 创建CLearScrollRequest
    ClearScrollRequest clearScrollRequest = new ClearScrollRequest();

    //11. 指定ScrollId
    clearScrollRequest.addScrollId(scrollId);

    //12. 删除ScrollId
    ClearScrollResponse clearScrollResponse = client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);

    //13. 输出结果
    System.out.println("删除scroll:" + clearScrollResponse.isSucceeded());

}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值