• 深分页Scroll


    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查询,如果地第一次拿到两个,剩下全在上下文中,这时,改变数据库,上下文中存的数据还是旧的,拿不到最新的

     

    1. # 执行scroll查询,返回第一页数据,并且将文档id信息存放在ES上下文中,指定生存时间1m
    2. POST /sms-logs-index/sms-logs-type/_search?scroll=1m
    3. {
    4. "query": {
    5. "match_all": {}
    6. },
    7. "size": 2,
    8. "sort": [ # 排序
    9. {
    10. "fee": {
    11. "order": "desc"
    12. }
    13. }
    14. ]
    15. }
    16. # 根据scroll查询下一页数据
    17. POST /_search/scroll
    18. {
    19. "scroll_id": "<根据第一步得到的scorll_id去指定>",
    20. "scroll": ""
    21. }
    22. # 删除scroll在ES上下文中的数据
    23. DELETE /_search/scroll/scroll_id

     

    1. // Java实现scroll分页
    2. @Test
    3. public void scrollQuery() throws IOException {
    4. //1. 创建SearchRequest
    5. SearchRequest request = new SearchRequest(index);
    6. request.types(type);
    7. //2. 指定scroll信息
    8. request.scroll(TimeValue.timeValueMinutes(1L));
    9. //3. 指定查询条件
    10. SearchSourceBuilder builder = new SearchSourceBuilder();
    11. builder.size(2);
    12. builder.sort("fee", SortOrder.DESC);
    13. builder.query(QueryBuilders.matchAllQuery());
    14. request.source(builder);
    15. //4. 获取返回结果scrollId,source
    16. SearchResponse resp = client.search(request, RequestOptions.DEFAULT);
    17. String scrollId = resp.getScrollId();
    18. System.out.println("----------首页---------");
    19. for (SearchHit hit : resp.getHits().getHits()) {
    20. System.out.println(hit.getSourceAsMap());
    21. }
    22. while(true) {
    23. //5. 循环 - 创建SearchScrollRequest
    24. SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
    25. //6. 指定scrollId的生存时间
    26. scrollRequest.scroll(TimeValue.timeValueMinutes(1L));
    27. //7. 执行查询获取返回结果
    28. SearchResponse scrollResp = client.scroll(scrollRequest, RequestOptions.DEFAULT);
    29. //8. 判断是否查询到了数据,输出
    30. SearchHit[] hits = scrollResp.getHits().getHits();
    31. if(hits != null && hits.length > 0) {
    32. System.out.println("----------下一页---------");
    33. for (SearchHit hit : hits) {
    34. System.out.println(hit.getSourceAsMap());
    35. }
    36. }else{
    37. //9. 判断没有查询到数据-退出循环
    38. System.out.println("----------结束---------");
    39. break;
    40. }
    41. }
    42. //10. 创建CLearScrollRequest
    43. ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
    44. //11. 指定ScrollId
    45. clearScrollRequest.addScrollId(scrollId);
    46. //12. 删除ScrollId
    47. ClearScrollResponse clearScrollResponse = client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
    48. //13. 输出结果
    49. System.out.println("删除scroll:" + clearScrollResponse.isSucceeded());
    50. }

  • 相关阅读:
    这两款简洁好看的软件你确定不想要吗
    前端-(4)
    医疗机器人技术研究现状
    Maven基础学习——tomcat插件配置(含web工程配置)
    新版idea配置maven注意点!!
    SQL中的字符串截取函数
    Spring理解,重要概念及图解,2023秋招spring常见八股文
    Leetcode 64. 最小路径和 动态规划+空间优化
    2024清理mac苹果电脑内存免费工具CleanMyMac X4.15
    linux Ubuntu 22.04工作区workspace介绍
  • 原文地址:https://blog.csdn.net/weixin_60934893/article/details/128047090