网站首页 > 开源技术 正文
深度分页问题大致可以分为两类
- 随机深度分页:随机跳转页面
- 滚动深度分页:只能一页一页往下查询
在旧版本,ES为深度分页有scroll search 的方式,官方的建议不用于实时的请求,
每一个 scroll_id 不仅会占用大量的资源(特别是排序的请求),而且会生成历史快照,对于数据的变更不会反映到快照上。这种方式用于非实时处理大量数据的情况。
实时深度分页采用search_after 的方式,这是在 >= 5.0 版本提供的功能。
基本思想:searchAfter的方式通过维护一个实时游标来避免scroll的缺点,它可以用于实时请求和高并发场景。
每个文档具有一个唯一值的字段用作排序的仲裁器。建议使用字段_id,它包含每个文档的一个唯一值。
search_after缺点
不能随机跳转分页,只能一页一页向后翻,需要至少指定一个唯一不重复字段来排序。
它与滚动API非常相似,但与它不同,search_after参数是无状态的,它始终针对最新版本的搜索器进行解析。因此,排序顺序可能会在步行期间发生变化,具体取决于索引的更新和删除。
例子
searchAfter将from...size中的from用searchAfter的sort字段表示,通过不断更新此sort字段实现向下滚动效果,但是和from不同的是对数据更新不敏感。
使用search_after要求search_after查询值和sort值相同,即字段必须相同。
search-after使用需知:
1 使用search-after时不要修改你的query(search_after)和sort字段
2 排序后的每条数据都是含有自己的sort值的,且他们都可以作为你接下来的search-after的值。
3 请确保你的sort中最后得到的值是唯一的,比如时间排序,精确度不高导致sort有可能重复,那么使用search-after后得到的值可能不符合你的预期。有可能有丢失,官方提供的思路是将_doc等元数据也放入排序字段中,因为_doc等数据一般是唯一的,将其加入一般可以保证你的sort字段唯一。
public static void main(String[] args) {
RestHighLevelClient restHighLevelClient = TestEsCreate.getEsClient("**.**.***.***:*****");//这里是创建RestHighLevelClient的实例,具体实现可以看我之前的代码
SearchRequest searchRequest = new SearchRequest("logstash-applog-*");
searchRequest.source(new SearchSourceBuilder().query(new BoolQueryBuilder()
.filter(QueryBuilders.termQuery("projectName", "*******"))
)
.size(10)
.sort("@timestamp", SortOrder.ASC)
.sort("_doc", SortOrder.ASC)
);
try{
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Object[] arrays = new Object[1];
for(SearchHit hit : searchResponse.getHits().getHits()){
Map<String, Object> map = hit.getSourceAsMap();
System.out.println(JSONObject.toJSONString(map));
System.out.println(hit.getSortValues()[0] + " " + hit.getSortValues()[1]); //打印sort值
arrays = hit.getSortValues();
}
SearchRequest searchRequest_2 = new SearchRequest("logstash-applog-*");
searchRequest_2.source(new SearchSourceBuilder().query(new BoolQueryBuilder()
.must(QueryBuilders.termQuery("projectName", "****"))
)
.size(10)
.sort("@timestamp", SortOrder.ASC)
.sort("_doc", SortOrder.ASC)
.searchAfter(arrays));
SearchResponse searchResponse_2 = restHighLevelClient.search(searchRequest_2, RequestOptions.DEFAULT);
for(SearchHit hit : searchResponse_2.getHits().getHits()){
Map<String, Object> map = hit.getSourceAsMap();
System.out.println(JSONObject.toJSONString(map));
System.out.println(hit.getSortValues()[0]);
arrays = hit.getSortValues();
}
SearchRequest searchRequest_3 = new SearchRequest("logstash-applog-*");
searchRequest_3.source(new SearchSourceBuilder().query(new BoolQueryBuilder()
.must(QueryBuilders.termQuery("projectName", "****"))
)
.size(10)
.sort("@timestamp", SortOrder.ASC)
.sort("_doc", SortOrder.ASC)
.searchAfter(arrays));
SearchResponse searchResponse_3 = restHighLevelClient.search(searchRequest_3, RequestOptions.DEFAULT);
for(SearchHit hit : searchResponse_3.getHits().getHits()){
Map<String, Object> map = hit.getSourceAsMap();
System.out.println(JSONObject.toJSONString(map));
System.out.println(hit.getSortValues()[0]);
}
}catch(Exception e){
e.printStackTrace();
}
}
猜你喜欢
- 2024-12-14 Spring Boot Data Elasticsearch 通用工具类
- 2024-12-14 SpringBoot+Vue+ES 实现仿百度全文搜索
- 2024-12-14 Spring Data JPA——多表设计、一对多、多对多、多表查询
- 2024-12-14 一文读懂SpringBoot整合Elasticsearch
- 2024-12-14 ElasticSearchRepository和ElasticSearchTemplate的使用
- 2024-12-14 Elasticsearch 在地理信息空间索引的探索和演进
- 2024-12-14 Java微服务-一套前后台全部开源的H5商城送给大家(全部开源)
- 2024-12-14 android使用greendao来保存数据
- 2024-12-14 纯干货,Spring-data-jpa详解,全方位介绍
- 2024-12-14 一套前后台全部开源的H5商城送给大家
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- jdk (81)
- putty (66)
- rufus (78)
- 内网穿透 (89)
- okhttp (70)
- powertoys (74)
- windowsterminal (81)
- netcat (65)
- ghostscript (65)
- veracrypt (65)
- asp.netcore (70)
- wrk (67)
- aspose.words (80)
- itk (80)
- ajaxfileupload.js (66)
- sqlhelper (67)
- express.js (67)
- phpmailer (67)
- xjar (70)
- redisclient (78)
- wakeonlan (66)
- tinygo (85)
- startbbs (72)
- webftp (82)
- vsvim (79)
本文暂时没有评论,来添加一个吧(●'◡'●)