这里写自定义目录标题
欢迎使用Markdown编辑器
使用
新的改变
import com.google.common.collect.ImmutableMap;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.ClearScrollRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.Scroll;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
*
*/
@Api("es滚动查询demo")
@RestController
@RequestMapping("/test")
@Slf4j
public class TestScroll {
@Autowired
private RestHighLevelClient restHighLevelClient;
/**
* 滚动查询
* <p>
* 第二次滚动要携带scrollId
*
* @return Map 结果,结构:↓
* {
* "total": 123,
* "list": [ {},{} ],
* "scrollId": "qqqqqqqqqqqqqqqqqqqqqqqqqq"
* }
*/
@ApiOperation("查询数据")
@GetMapping
public Map getScroll(@RequestParam(required = false) @ApiParam("滚动id,第一次滚动不需要传") String scrollId, @RequestParam(required = false, defaultValue = "10") @ApiParam("滚动大小") int size, @RequestParam(required = false) @ApiParam("查询条件1") String param) {
final String index = "index*";
//检索条件
QueryBuilder queryBuilder = param == null ? null : QueryBuilders.termsQuery("param", param);
SearchResponse searchResponse = null;
//scrollId为空表示第一次滚动
if (StringUtils.isBlank(scrollId)) {
//第一次滚动保持时间
final long fristKeepMinutes = 2;
searchResponse = firstScroll(index, queryBuilder, null, size, fristKeepMinutes);
} else {
final long scrollKeepMinutes = 1;
searchResponse = manyTimesScroll(scrollId, scrollKeepMinutes);
}
return ElasticsearchResponseResultBuilder(searchResponse);
}
/**
* 第一次滚动
*
* @param index 索引(可以使用通配符)
* @param queryBuilder 查询条件
* @param size 滚动页大小
* @param keepAlive 滚动保持时间,单位:分钟
**/
private SearchResponse firstScroll(String index, QueryBuilder queryBuilder, FieldSortBuilder order, int size, long keepAlive) {
SearchRequest searchRequest = new SearchRequest(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.size(size);
if (queryBuilder != null) searchSourceBuilder.query(queryBuilder);
if (order != null) searchSourceBuilder.sort(order);
searchRequest.source(searchSourceBuilder);
Scroll scroll = new Scroll(TimeValue.timeValueMinutes(keepAlive));
searchRequest.scroll(scroll);
SearchResponse response = null;
try {
response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
/**
* 第二次+ 滚动
*
* @param scrollId 滚动id。es根据此id继续滚动
* @param keepAlive 更新滚动时间,单位:分钟
*/
private SearchResponse manyTimesScroll(String scrollId, long keepAlive) {
SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
scrollRequest.scroll(TimeValue.timeValueMinutes(keepAlive));
SearchResponse response = null;
try {
//根据上次的滚动参数继续滚动查询,不需要重新设置
response = restHighLevelClient.scroll(scrollRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
/**
* 结果封装
*/
private Map ElasticsearchResponseResultBuilder(SearchResponse response) {
if (response == null) {
return null;
}
SearchHit[] hits = response.getHits().getHits();
List resultList = new ArrayList(hits.length);
for (SearchHit hit : hits) {
resultList.add(hit.getSourceAsMap());
}
return ImmutableMap.of(
"total", response.getHits().getTotalHits().value,
"list", resultList,
"scrollId", response.getScrollId()
);
}
@ApiOperation(value = "清理滚动", notes = "个人认为同一个滚动scrollId发生改变,旧的scrollId可能已经失效了,不需要清理")
@DeleteMapping
public void clear(String scrollId) {
//清理scroll,释放资源
ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
clearScrollRequest.addScrollId(scrollId);
try {
restHighLevelClient.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
} catch (Exception e) {
log.error("清理滚动异常,scrollId{}", scrollId);
e.printStackTrace();
}
}
}