按照一般的查询流程来说,如果我想查询前10条数据:

· 1 客户端请求发给某个节点

· 2 节点转发给个个分片,查询每个分片上的前10条

· 3 结果返回给节点,整合数据,提取前10条

· 4 返回给请求客户端

那么当我想要查询第10条到第20条的数据该怎么办呢?这个时候就用到分页查询了。

浅分页可以理解为简单意义上的分页。它的原理很简单,就是查询前20条数据,然后截断前10条,只返回10-20的数据。这样其实白白浪费了前10条的查询。

构造数据:

/**插入一百条数据*/
@Test
// 批量查询100条记录
public void createDocument100() throws Exception {
   for(int i=1;i<=100;i++){
       XContentBuilder builder = null;
       try {
           builder = jsonBuilder()
                  .startObject()
                  .field("title", "第"+i+"本书")
                  .field("author", "作者"+i)
                  .field("id" , i)
                  .field("message", i+"是英国物理学家斯蒂芬·霍金创作的科学著作,首次出版于1988年。全书共十二章,讲的全都是关于宇宙本性的最前沿知识,包括:我们的宇宙图像、空间和时间、膨胀的宇宙、不确定性原理、黑洞、宇宙的起源和命运等内容,深入浅出地介绍了遥远星系、黑洞、粒子、反物质等知识")
                  .endObject();
           String json = builder.string();
           IndexResponse response = this.client.prepareIndex("blog2", "article")
                  .setSource(json, XContentType.JSON)
                  .get();
           // 索引名称
           String _index = response.getIndex();
           // 类型
           String _type = response.getType();
           // 文档ID
           String _id = response.getId();
           // 版本
           long _version = response.getVersion();
           // 返回的操作状态
           RestStatus status = response.status();
           System.out.println("索引名称:"+_index+" "+"类型 :" +  _type + " 文档ID:"+_id+" 版本 :"+_version+" 返回的操作状态:"+status);
​
      } catch (IOException e) {
           e.printStackTrace();
      }
  }
}
​
​

1.9.1:浅分页

/**
* 查询所有的方法
searchRequestBuilder 的 setFrom【从0开始】 和 setSize【查询多少条记录】方法实现
* */
@Test
public void sortPages(){
   // 搜索数据
   // get() === execute().actionGet()
   SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch("blog2").setTypes("article")
          .setQuery(QueryBuilders.matchAllQuery());//默认每页10条记录
   final long totalHits = searchRequestBuilder.get().getHits().getTotalHits();//总条数
   final int pageDocument = 10 ;//每页显示多少条
   final long totalPage = totalHits / pageDocument;//总共分多少页
   for(int i=1;i<=totalPage;i++){
       System.out.println("=====================当前打印的是第 :"+i+" 页==============");
       //setFrom():从第几条开始检索,默认是0。
       //setSize():查询多少条文档。
       searchRequestBuilder.setFrom(i*pageDocument).setSize(pageDocument);
​
       SearchResponse searchResponse = searchRequestBuilder.get();
       SearchHits hits = searchResponse.getHits();
       Iterator<SearchHit> iterator = hits.iterator();
       while (iterator.hasNext()) {
           SearchHit searchHit = iterator.next(); // 每个查询对象
           System.out.println(searchHit.getSourceAsString()); // 获取字符串格式打印
      }
  }
}
​
​

1.9.2:分页优化-深分页(scroll)

对于上面介绍的浅分页,当Elasticsearch响应请求时,它必须确定docs的顺序,排列响应结果。

如果请求的页数较少(假设每页20个docs), Elasticsearch不会有什么问题,但是如果页数较大时,比如请求第20页,Elasticsearch不得不取出第1页到第20页的所有docs,再去除第1页到第19页的docs,得到第20页的docs。

解决的方式就是使用scroll,scroll就是维护了当前索引段的一份快照信息--缓存(这个快照信息是你执行这个scroll查询时的快照)在这个查询后的任何新索引进来的数据,都不会在这个快照中查询到。但是它相对于from和size,不是查询所有数据然后剔除不要的部分,而是记录一个读取的位置,保证下一次快速继续读取。

可以把 scroll 分为初始化和遍历两步: 1、初始化时将所有符合搜索条件的搜索结果缓存起来,可以想象成快照; 2、遍历时,从这个快照里取数据,也就是说,在初始化后对索引插入、删除、更新数据都不会影响遍历结果

@Test
public void scrollPages(){
   //获取Client对象,设置索引名称,搜索类型(SearchType.SCAN)[5.4移除,对于java代码,直接返回index顺序,不对结果排序],搜索数量,发送请求
   SearchResponse searchResponse = transportClient
      .prepareSearch("blog2")
          .setSearchType(SearchType.DEFAULT)//执行检索的类别
          .setSize(10).setScroll(new TimeValue(1000)).execute()
          .actionGet();//注意:首次搜索并不包含数据
   //获取总数量
   long totalCount = searchResponse.getHits().getTotalHits();
​
   int page=(int)totalCount/(10);//计算总页数
   System.out.println("总页数: ================="+page+"=============");
   for (int i = 1; i <= page; i++) {
       System.out.println("=========================页数:"+i+"====================");
​
       searchResponse = transportClient
              .prepareSearchScroll(searchResponse.getScrollId())//再次发送请求,并使用上次搜索结果的ScrollId
              .setScroll(new TimeValue(1000)).execute()
              .actionGet();
       SearchHits hits = searchResponse.getHits();
       for (SearchHit searchHit : hits) {
​
           System.out.println(searchHit.getSourceAsString()); // 获取字符串格式打印
      }
​
  }
}
​
​

es之java分页操作的更多相关文章

  1. es之java索引操作

    1.7.1: 创建索引 /** * 创建索引 * */ @Test public void createIndex(){ // 创建索引 CreateIndexResponse blog2 = cli ...

  2. Java文件操作系列[1]——PDFBox实现分页提取PDF文本

    需求:用java分页提取PDF文本. PDFBox是一个很好的可以满足上述需求的开源工具. 1.PDF文档结构 要解析PDF文本,我们首先要了解PDF文件的结构. 关于PDF文档,最重要的几点: 一, ...

  3. 【ELK】4.spring boot 2.X集成ES spring-data-ES 进行CRUD操作 完整版+kibana管理ES的index操作

    spring boot 2.X集成ES 进行CRUD操作  完整版 内容包括: ============================================================ ...

  4. 数据你把它的金额-JAVA分页

    数据量你造吗-JAVA分页 原创地址:   http://www.cnblogs.com/Alandre/  (泥沙砖瓦浆木匠),须要转载的,保留下! Thanks 学习的心态第一,解行要对应. 事实 ...

  5. 数据量你造吗-JAVA分页

    原创地址:   http://www.cnblogs.com/Alandre/  (泥沙砖瓦浆木匠),需要转载的,保留下! Thanks 学习的心态第一,解行要相应.其实<弟子规>在“余力 ...

  6. JAVA文件操作类和文件夹的操作代码示例

    JAVA文件操作类和文件夹的操作代码实例,包括读取文本文件内容, 新建目录,多级目录创建,新建文件,有编码方式的文件创建, 删除文件,删除文件夹,删除指定文件夹下所有文件, 复制单个文件,复制整个文件 ...

  7. MongoDB学习-->命令行增删改查&JAVA驱动操作Mongodb

    MongoDB 是一个基于分布式文件存储的数据库. 由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关 ...

  8. ES(Elastic Search)update操作设置无 docment时进行insert

    最近使用一套数据加工中间工具,查看es操作中的update操作.其中方法命名为updateOrInsert.但是没发现代码中有ES的insert方法调用.于是仔细分析了代码逻辑. 经过一路追溯,直至E ...

  9. MongoDB Java API操作很全的整理

    MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写,一般生产上建议以共享分片的形式来部署. 但是MongoDB官方也提供了其它语言的客户端操作API.如下图所示: 提供了C.C++ ...

随机推荐

  1. 《深入浅出WPF》学习总结之控件与布局

    一.控件到底是什么 控件的本质是“数据+算法”——用户输入原始数据,算法处理原始数据并得到结果数据.问题就在于程序如何将结果数据展示给用户.同样一组数据,你可以使用LED阵列显示出来,或者是以命令行模 ...

  2. linux 系统目录权限

    小结: 目录的读.写.执行权限 1. 可读r:表示具有浏览目录 下面文件及子目录的权限 ls dir 1)如果没有x权限,则不能进到目录,既无法执行cd dir 2)如果没有x权限,ls列表时可以看到 ...

  3. Simplify Path(路径简化)

    问题: 来源:https://leetcode.com/problems/simplify-path Given an absolute path for a file (Unix-style), s ...

  4. 使用批处理命令注册运行mysql数据库,无需注册mysql服务,可以在任意电脑登录使用

    使用批处理命令初始化和开启mysql服务,移植数据库之后可以直接运行访问,对于学习数据库的人来说特别的方便哦. 我们可以从mysql官网下载官方社区版本的mysql: 这里使用之前下载的8.0.15来 ...

  5. Luogu P1084 [NOIP2012]疫情控制

    题目 首先我们二分一下答案. 然后我们用倍增让军队往上跳,最多先跳到根的子节点. 如果当前军队可以到达根节点,那么记录一下它的编号和它到达根节点后还可以走的时间. 并且我们记录根节点的叶子节点上到根节 ...

  6. 实例学习——爬取豆瓣网TOP250数据

    开发环境:(Windows)eclipse+pydev 网址:https://book.douban.com/top250?start=0 from lxml import etree #解析提取数据 ...

  7. B - 卿学姐与基本法 (离散化+成段更新+区间求和)

    卿学姐与基本法 Time Limit: 2000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit S ...

  8. link标签中rel属性的作用

    Link标签有两个作用:1. 定义文档与外部资源的关系:2. 是链接样式表.link标签是用于当前文档引用外部文档的 这个标签的rel属性用于设置对象和链接目标间的关系,说白了就是指明你链进来的对象是 ...

  9. 实现webpack的实时打包构建

    1. 由于每次重新修改代码之后,都需要手动运行webpack打包的命令,比较麻烦,所以使用`webpack-dev-server`来实现代码实时打包编译,当修改代码之后,会自动进行打包构建.2. 运行 ...

  10. vue中项目如何引入sass (vue-cli项目)

    1.进入项目目录 2.安装sass的依赖 npm install --save-dev sass-loader npm install --save-dev node-sass 3.在build文件夹 ...