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查询,返回第一页数据,并且将文档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": "
" - }
-
-
- # 删除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());
-
- }