封装es查询
快速实现es的各种查询的功能包括关系型数据库中的and、between、in、like、sortField、sortDirect 分页和高亮显示等
快速开始!只需构造对应的参数调用方法即可
1.首先创建es客户端实例,连接es
(双重校验锁实现单例,线程安全,节约资源)
//用来将客户端对象存储起来,避免多次实例化
private volatile static Map<String,RestHighLevelClient> clientMap=new ConcurrentHashMap<String,RestHighLevelClient>();
//抽取从es中查询数据需要的公共代码,只需要加载一次,避免每次查询均加载
//用SearchSourceBuilder来构造查询请求体
static SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
static {
//搜索范围,只取第一个
sourceBuilder.from(0);
sourceBuilder.size(1);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//指定排序
sourceBuilder.sort(new FieldSortBuilder("fileUploadTime").order(SortOrder.DESC));
}
//传入参数,获取客户端(采用对象池模式,一个地址只一次创建,永久使用)
public static RestHighLevelClient getClient(String url,int port,String loginName,String password){
//将url和端口拼接起来作为客户端对象的唯一标识
String clientId=url+":"+port;
RestHighLevelClient client=clientMap.get(clientId);
if(client == null) {
synchronized (EsUtil.class) {
if(client == null) {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(loginName, password));
client =new RestHighLevelClient(
RestClient.builder(
new HttpHost(url,port)
).setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
httpClientBuilder.disableAuthCaching();
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
})
);
logger.info(clientId+"创建了RestHighLevelClient客户端");
clientMap.put(clientId, client);
}
}
}
return client;
}
2.接口接收参数,调用方法返回查询数据
@PostMapping(value = "/getpage")
public ServiceResult getpage(@RequestBody String json) {
try {
com.alibaba.fastjson.JSONObject jSONObject = JSON.parseObject(json);
String index = jSONObject.get("index").toString();
String type = jSONObject.get("type").toString();
Map<String, Object> andParam = jSONObject.get("andParam") == null ? null : (Map<String, Object>) JSON.parseObject(jSONObject.get("andParam").toString());
Map<String, Object> timeBetweenParam = jSONObject.get("timeBetweenParam") == null ? null : (Map<String, Object>) JSON.parseObject(jSONObject.get("timeBetweenParam").toString());
Map<String, Object> numberBetweenParam = jSONObject.get("numberBetweenParam") == null ? null : (Map<String, Object>) JSON.parseObject(jSONObject.get("numberBetweenParam").toString());
Map<String, Object> inParam = jSONObject.get("inParam") == null ? null : (Map<String, Object>) JSON.parseObject(jSONObject.get("inParam").toString());
Map<String, Object> notinParam = jSONObject.get("notinParam") == null ? null : (Map<String, Object>) JSON.parseObject(jSONObject.get("notinParam").toString());
Map<String, Object> likeParam = jSONObject.get("likeParam") == null ? null : (Map<String, Object>) JSON.parseObject(jSONObject.get("likeParam").toString());
String sortField = jSONObject.get("sortField") == null ? null : jSONObject.get("sortField").toString();
String sortDirection = jSONObject.get("sortDirection") == null ? null : jSONObject.get("sortDirection").toString();
Integer currentPage = jSONObject.get("currentPage") == null ? null : Integer.valueOf(jSONObject.get("currentPage").toString());
Integer pageSize = jSONObject.get("pageSize") == null ? null : Integer.valueOf(jSONObject.get("pageSize").toString());
EsPage esPage = ElasticsearchRestClientUtils.searchDataPage(
index, type,
andParam,
timeBetweenParam,
numberBetweenParam,
inParam,
notinParam,
likeParam,
sortField, sortDirection,
currentPage, pageSize,
null, null
);
return new ServiceResult().setRSP(null, null, esPage);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
return new ServiceResult().setRSP("50001", e.getMessage(), null);
}
}
public static EsPage searchDataPage(String index, String type,
Map<String, Object> andParam,
Map<String, Object> timeBetweenParam,
Map<String, Object> numberBetweenParam,
Map<String, Object> inParam,
Map<String, Object> notinParam,
Map<String, Object> likeParam,
String sortField, String sortDirection,
Integer currentPage, Integer pageSize,
String highlightField,
String queryFields) throws Exception {
SearchResponse searchResponse = getSearchResponse(index, type,
andParam,
timeBetweenParam,
numberBetweenParam,
inParam, notinParam,
likeParam,
sortField, sortDirection,
currentPage, pageSize,
highlightField, queryFields,
false);
long totalHits = searchResponse.getHits().totalHits;
long length = searchResponse.getHits().getHits().length;
log.debug("共查询到[{}]条数据,处理数据条数[{}]", totalHits, length);
if (searchResponse.status().getStatus() == 200) {
// 解析对象
List<Map<String, Object>> sourceList = setSearchResponse(searchResponse, highlightField);
return new EsPage(currentPage, pageSize, (int) totalHits, sourceList);
}
return null;
}
private static SearchResponse getSearchResponse(
String index, String type,
Map<String, Object> andParam,
Map<String, Object> timeBetweenParam,
Map<String, Object> numberBetweenParam,
Map<String, Object> inParam,
Map<String, Object> notinParam,
Map<String, Object> likeParam,
String sortField, String sortDirection,
Integer currentPage, Integer pageSize,
String highlightField,
String queryFields,
Boolean isExport) throws Exception {
SearchRequest request = new SearchRequest(index).types(type);
SearchSourceBuilder searchRequestBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//字段精准查询
if (null != andParam && andParam.size() > 0) {
for (Map.Entry<String, Object> map : andParam.entrySet()) {
Object value = map.getValue();
if (null != value && !value.toString().trim().equals("")) {
boolQuery.filter(QueryBuilders.termQuery(map.getKey(), map.getValue()));
}
}
}
//时间区间查询
if (null != timeBetweenParam && timeBetweenParam.size() > 0) {
String[] timeBetween = null;
for (Map.Entry<String, Object> map : timeBetweenParam.entrySet()) {
Object value = map.getValue();
if (null != value && !value.toString().trim().equals("")) {
timeBetween = value.toString().split(",");
boolQuery.filter(QueryBuilders.rangeQuery(map.getKey())
.format("yyyy-MM-dd HH:mm:ss")
.from(timeBetween[0])
.to(timeBetween[1])
.includeLower(true)//true包含下界<=,false 不包含下界<
.includeUpper(true));//true包含上界>=,false 不包含上界>
}
}
}
//数字区间查询
if (null != numberBetweenParam && numberBetweenParam.size() > 0) {
String[] numberBetween = null;
for (Map.Entry<String, Object> map : numberBetweenParam.entrySet()) {
Object value = map.getValue();
if (null != value && !value.toString().trim().equals("")) {
numberBetween = value.toString().split(",");
boolQuery.filter(QueryBuilders.rangeQuery(map.getKey())
.from(numberBetween[0])
.to(numberBetween[1])
.includeLower(true)//true包含下界<=,false 不包含下界<
.includeUpper(true));//true包含上界>=,false 不包含上界>
}
}
}
//in查询
if (null != inParam && inParam.size() > 0) {
for (Map.Entry<String, Object> map : inParam.entrySet()) {
Object value = map.getValue();
if (null != value && !value.toString().trim().equals("")) {
boolQuery.filter(QueryBuilders.termsQuery(map.getKey(), map.getValue().toString().split(",")));
}
}
}
//not in查询
if (null != notinParam && notinParam.size() > 0) {
BoolQueryBuilder inFilter = QueryBuilders
.boolQuery();
for (Map.Entry<String, Object> map : notinParam.entrySet()) {
Object value = map.getValue();
if (null != value && !value.toString().trim().equals("")) {
for (String notinValue : map.getValue().toString().split(",")) {
if (null != notinValue && !notinValue.equals("")) {
inFilter.mustNot(QueryBuilders.termQuery(map.getKey(), notinValue));
}
}
}
}
boolQuery.filter(inFilter);
}
//likeParam
if (null != likeParam && likeParam.size() > 0) {
BoolQueryBuilder likeFilter = QueryBuilders
.boolQuery();
for (Map.Entry<String, Object> map : likeParam.entrySet()) {
Object value = map.getValue();
if (null != value && !value.toString().trim().equals("")) {
for (String phraseValue : map.getValue().toString().split(",")) {
if (null != phraseValue && !phraseValue.equals("")) {
likeFilter.should(QueryBuilders.matchPhraseQuery(map.getKey(), phraseValue));
}
}
}
}
boolQuery.filter(likeFilter);
}
// 高亮(xxx=111,aaa=222)
if (StringUtils.isNotEmpty(highlightField)) {
HighlightBuilder highlightBuilder = new HighlightBuilder();
//highlightBuilder.preTags("<span style='color:red' >");//设置前缀
//highlightBuilder.postTags("</span>");//设置后缀
// 设置高亮字段
highlightBuilder.field(highlightField);
searchRequestBuilder.highlighter(highlightBuilder);
}
searchRequestBuilder.query(boolQuery);
//只查询某些字段
if (StringUtils.isNotEmpty(queryFields)) {
searchRequestBuilder.fetchSource(queryFields.split(","), null);
}
searchRequestBuilder.fetchSource(true);
//排序
if (StringUtils.isNotEmpty(sortField)) {
searchRequestBuilder.sort(sortField, SortOrder.fromString(sortDirection));
} else {
// 设置是否按查询匹配度排序
searchRequestBuilder.explain(true);
}
if (null != isExport && isExport) {//是否导出
//导出使用scroll滚动查询
final Scroll scroll = new Scroll(new TimeValue(60000 * 5));
request.scroll(scroll);
} else {//非导出使用简单查询
if (null != currentPage && null != pageSize) {
//分页
searchRequestBuilder.from((currentPage - 1) * pageSize).size(pageSize);
} else {
//不分页查询全部(不设置size默认值返回10条记录)
searchRequestBuilder.size(10000);
}
}
//打印的内容 可以在 Elasticsearch head 和 Kibana 上执行查询
log.info("\n{}", searchRequestBuilder);
request.source(searchRequestBuilder);
SearchResponse searchResponse = client.search(request);
return searchResponse;
}
private static List<Map<String, Object>> setSearchResponse(SearchResponse searchResponse, String highlightField) {
List<Map<String, Object>> sourceList = new ArrayList<Map<String, Object>>();
StringBuffer stringBuffer = new StringBuffer();
for (SearchHit searchHit : searchResponse.getHits().getHits()) {
searchHit.getSourceAsMap().put("id", searchHit.getId());
if (StringUtils.isNotEmpty(highlightField)) {
System.out.println("遍历 高亮结果集,覆盖 正常结果集" + searchHit.getSourceAsMap());
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());
}
return sourceList;
}