1、from+size
//分页查询
@RequestMapping(value = "/get", method = RequestMethod.GET)
public BaseResponse<List<Object>> get(@RequestParam int from ,@RequestParam int size) {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//排序
searchSourceBuilder.sort("timestamp", SortOrder.ASC);
//筛选返回的字段,只要referer和clientip
searchSourceBuilder.fetchSource(new String[]{"referer", "clientip"},null);
searchSourceBuilder.from(from*size);
searchSourceBuilder.size(size);
SearchResponse response = transportClient.prepareSearch("kibana_sample_data_logs").setTypes("_doc")
//设置查询类型java
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setSource(searchSourceBuilder)
.get();
SearchHits hits = response.getHits();
Map<String, String> map = new HashMap<>();
for(int i=0;i<hits.getHits().length;i++) {
Map<String, Object> sourceAsMap = hits.getHits()[i].getSourceAsMap();
System.out.println(JSONObject.toJSONString(sourceAsMap));
map.put(hits.getHits()[i].getId(),hits.getHits()[i].getIndex());
}
return BaseResponse.ok(map);
}
建议:避免过度使用 from 和 size 来分页或一次请求太多结果,深度分页问题。
注意:max_result_window默认10000,分页查询超过10000会报错,可以修改这个值(不建议)
2、search_after
@RequestMapping(value = "/searchAfter", method = RequestMethod.GET)
public BaseResponse<List<Object>> searchAfter(@RequestParam int size,
@RequestParam Long searchAfter) {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//排序字段
searchSourceBuilder.sort("timestamp", SortOrder.ASC);
//筛选返回的字段,只要referer和clientip
searchSourceBuilder.fetchSource(new String[]{"referer", "clientip"}, null);
//上一页最后数据sort值,这个参数应该是个数组,数组的个数与排序字段个数一致,必填字段,首页时为-1,
searchSourceBuilder.searchAfter(new Object[]{searchAfter});
//不用传,默认0
searchSourceBuilder.from(0);
searchSourceBuilder.size(size);
SearchResponse response = transportClient.prepareSearch("kibana_sample_data_logs").setTypes("_doc")
//设置查询类型java
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setSource(searchSourceBuilder)
.get();
SearchHits hits = response.getHits();
Map<String, String> map = new HashMap<>();
for (int i = 0; i < hits.getHits().length; i++) {
Map<String, Object> sourceAsMap = hits.getHits()[i].getSourceAsMap();
System.out.println(JSONObject.toJSONString(sourceAsMap));
map.put(hits.getHits()[i].getId(), hits.getHits()[i].getIndex());
}
//这个值就是排序字段sort值,需要返回,下一页请求时带过来
map.put("searchAfter",String.valueOf(Arrays.stream(hits.getHits()[hits.getHits().length-1].getRawSortValues()).findFirst().get()));
return BaseResponse.ok(map);
}
对比:
from size,深度分页或者size特别大的情况,会出深度分页问题,max_result_window也会阻预设的查询。
search_after: 性能优秀,是分页的优化。
深度分页问题可以从业务上想办法避免是最好的
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)