使用from size进行分页查询(深度分页),当数据量大的时候,对全部数据进行遍历,使用from size性能会很差。from指的是从哪里开始拿数据,size是结果集中返回的文档个数。from-size的工作原理是:如size=10&from=100,那么Elasticsearch会从每个分片里取出110条数据,然后汇集到一起再排序,取出101~110序号的文档。由此可见,from-size的效率必然不会很高,特别是分页越深,需要排序的数据越多,其效率就越低。
Elasticsearch中进行大数据量查询时,往往因为设备、网络传输问题影响查询数据的效率;Elasticsearch中提供了Scroll(游标)的方式对数据进行少量多批次的滚动查询,来提高查询效率。
/** * 查询所有数据 * * @param index 索引名称 * @param type type 6.0后不推荐使用 * @param fields 需要显示的字段 * @param sortField 需要进行排序的字段 * @param highlightField 需要高亮的字段 * @param queryBuilder 查询条件 * @return */ public static List<Map<String, Object>> searchAllData(String index, String type, String fields, String sortField, String highlightField,QueryBuilder queryBuilder ) { //指定一个index和type SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes(type); // 高亮(xxx=111,aaa=222) if (StringUtils.isNotEmpty(highlightField)) { HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.preTags("<span style='color:red;font-weight:bold'>");//设置前缀 highlightBuilder.postTags("</span>");//设置后缀 // 设置高亮字段 highlightBuilder.field(highlightField); searchRequestBuilder.highlighter(highlightBuilder); } // 需要显示的字段,逗号分隔(缺省为全部字段) if (StringUtils.isNotEmpty(fields)) { searchRequestBuilder.setFetchSource(fields.split(","), null); } searchRequestBuilder.setFetchSource(true); if (StringUtils.isNotEmpty(sortField)) { searchRequestBuilder.addSort(sortField, SortOrder.ASC); } //设置每批读取的数据量 searchRequestBuilder.setSize(100); //查询条件 searchRequestBuilder.setQuery(queryBuilder); //设置 search context 维护1分钟的有效期 searchRequestBuilder.setScroll(TimeValue.timeValueMinutes(1)); //获得首次的查询结果 SearchResponse scrollResp=searchRequestBuilder.get(); //打印的内容 可以在 Elasticsearch head 和 Kibana 上执行查询 LOGGER.info("\n{}", searchRequestBuilder); //打印命中数量 LOGGER.info("命中总数量:{}", scrollResp.getHits().getTotalHits()); List<Map<String, Object>> sourceList = new ArrayList<Map<String, Object>>(); StringBuffer stringBuffer = new StringBuffer(); do { //将scorllId循环传递 scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(TimeValue.timeValueMinutes(1)).execute().actionGet(); for (SearchHit searchHit : scrollResp.getHits().getHits()) { searchHit.getSourceAsMap().put("id", searchHit.getId()); if (StringUtils.isNotEmpty(highlightField)) { if (!ObjectUtils.isEmpty(searchHit.getHighlightFields().get(highlightField))) { Text[] text = searchHit.getHighlightFields().get(highlightField).getFragments(); if (text != null) { for (Text str : text) { stringBuffer.append(str.string()); } //遍历 高亮结果集,覆盖 正常结果集 searchHit.getSourceAsMap().put(highlightField, stringBuffer.toString()); } } } sourceList.add(searchHit.getSourceAsMap()); } //当searchHits的数组为空的时候结束循环,至此数据全部读取完毕 } while(scrollResp.getHits().getHits().length != 0); //删除scroll ClearScrollRequest clearScrollRequest = new ClearScrollRequest(); clearScrollRequest.addScrollId(scrollResp.getScrollId()); client.clearScroll(clearScrollRequest).actionGet(); return sourceList; }
————————————————
版权声明:本文为CSDN博主「Haoyugg」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_41127890/article/details/82219811