rest client全套封装好的java调用elasticsearch功能的工具类,亲测可用,返回数据全面
**
1.pom 依赖
**
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.39</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>6.4.0</version>
</dependency>
**
2.配置类
**
package com.lenient.ybg.config.ES;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.message.BasicHeader;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
/**
* @author lenient
* @date 2020/9/23 10:56
* es配置类
* 基于HTTP的客户端REST Client(推荐使用),官方给出来的REST Client有Java Low Level REST Client和Java Hight Level REST Client两个,前者兼容所有版本的ES
*/
@Configuration
public class RestConfig {
@Value("${elasticsearch.hostname}")
private String hostname;
@Value("${elasticsearch.port}")
private int port;
@Value("${elasticsearch.scheme}")
private String scheme;
@Bean
public RestClient getClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
// 如果有多个从节点可以持续在内部new多个HttpHost,参数1是ip,参数2是HTTP端口,参数3是通信协议
HttpHost httpHost2 = new HttpHost(hostname, port, scheme);
RestClientBuilder clientBuilder = RestClient.builder(httpHost2);
// 设置超时时间,多次尝试同一请求时应该遵守的超时。默认值为30秒,与默认套接字超时相同。若自定义套接字超时,则应相应地调整最大重试超时
clientBuilder.setMaxRetryTimeoutMillis(40000);
// 设置请求头,每个请求都会带上这个请求头
Header[] defaultHeaders = {new BasicHeader("charset", "utf-8"),
new BasicHeader("content-type", "application/json")};
clientBuilder.setDefaultHeaders(defaultHeaders);
// 最后配置好的clientBuilder再build一下即可得到真正的Client
return clientBuilder.build();
}
}
**
3.统一返回类
**
package com.lenient.ybg.baseBean;
/**
* @ClassName ResultBean
* @author: Lenient
* @date: 2021/5/20 10:12
* @description:
* @explain 统一数据返回类型
*/
public class ResultBean {
/*状态码*/
private Integer code;
/*返回消息*/
private String msg;
/*返回数据*/
private Object data;
public static ResultBean succees(Integer code,String msg,Object data){
ResultBean resultBean= new ResultBean();
resultBean.setCode(code);
resultBean.setMsg(msg);
resultBean.setData(data);
return resultBean;
}
public static ResultBean succees(String msg,Object data){
Integer code=200;
return succees( code, msg, data);
}
public static ResultBean succees(Object data){
Integer code=200;
String msg="成功";
return succees( code, msg, data);
}
public static ResultBean succees(Integer code){
String msg="成功";
Object data=null;
return succees( code, msg, data);
}
public static ResultBean succees(Integer code,String msg){
Object data=null;
return succees( code, msg, data);
}
public static ResultBean succees(Integer code,Object data){
String msg="成功";
return succees( code, msg, data);
}
public static ResultBean succees(String msg){
Integer code=200;
Object data=null;
return succees( code, msg, data);
}
public static ResultBean error(Integer code,String msg,Object data){
ResultBean resultBean= new ResultBean();
resultBean.setCode(code);
resultBean.setMsg(msg);
resultBean.setData(data);
return resultBean;
}
public static ResultBean error(String msg,Object data){
Integer code=400;
return succees( code, msg, data);
}
public static ResultBean error(Object data){
Integer code=400;
String msg="失败";
return succees( code, msg, data);
}
public static ResultBean error(Integer code){
String msg="失败";
Object data=null;
return succees( code, msg, data);
}
public static ResultBean error(Integer code,String msg){
Object data=null;
return succees( code, msg, data);
}
public static ResultBean error(Integer code,Object data){
String msg="失败";
return succees( code, msg, data);
}
public static ResultBean error(String msg){
Integer code=400;
Object data=null;
return succees( code, msg, data);
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
@Override
public String toString() {
return "ResultBean{" +
"code=" + code +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}
**
4.工具类
**
package com.lenient.ybg.config.ES;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lenient.ybg.baseBean.ResultBean;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.ContentType;
import org.apache.http.nio.entity.NStringEntity;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.io.IOException;
/**
* @ClassName EsUitls
* @author: Lenient
* @date: 2021/5/19 9:00
* @description:
* @explain
*/
@Configuration
public class EsUtils {
private final static Logger LOGGER = LoggerFactory.getLogger(EsUtils.class);
@Autowired
private RestClient restClient;
private static RestClient client;
/*
* @Author lenient
* @explain @PostConstruct该注解被用来修饰一个非静态的void()方法。
* 被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。
* PostConstruct在构造函数之后执行,init()方法之前执行。
* 应用:在静态方法中调用依赖注入的Bean中的方法
* @Date 9:06 2021/5/19
* @Description
* @Param []
* @return void
**/
@PostConstruct
public void init(){
client=this.restClient;
}
/**
* @Author lenient
* @explain 判断索引是否存在
* @Date 11:09 2021/5/19
* @Description
* @Param [index]
* @return boolean
**/
public static ResultBean isIndexExist(String index) {
//构建HTTP 请求
Request request=new Request("GET",
new StringBuilder("/"+index).toString()
);
//发送HTTP请求 performRequest是同步的,将阻塞调用线程并在请求成功时返回Response
try {
Response response = client.performRequest(request);
int statusCode = response.getStatusLine().getStatusCode();
String str = EntityUtils.toString(response.getEntity());
return ResultBean.succees(statusCode,"true",str);
} catch (IOException e) {
//如果索引不存在会抛出异常
return ResultBean.succees("false",e);
}
}
/*
* @Author lenient
* @explain 创建索引
* @Date 13:50 2021/5/19
* @Description
* @Param [index(索引名(必须小写)), query(指定类型,字段等)
* 如:{"settings":{"index":{"number_of_shards":3,"number_of_replicas":2}}}
* ]
* @return boolean
**/
public static ResultBean createIndex(String index, String query){
if(StringUtils.isNotBlank(index)){
//构建HTTP 请求
Request request=new Request("PUT", new StringBuilder(index).toString());
if(StringUtils.isNotBlank(query)){
NStringEntity nStringEntity=new NStringEntity(query, ContentType.APPLICATION_JSON);
request.setEntity(nStringEntity);
}
try {
Response response = client.performRequest(request);
int statusCode = response.getStatusLine().getStatusCode();
String str = EntityUtils.toString(response.getEntity());
return ResultBean.succees(statusCode,"true",str);
}catch (Exception e){
return ResultBean.error(e);
}
}else {
return ResultBean.error("index不能为空");
}
}
/*
* @Author lenient
* @explain 创建索引
* @Date 14:59 2021/5/19
* @Description
* @Param [index(索引名)]
* @return boolean
**/
public static ResultBean createIndex(String index){
String query=null;
return createIndex( index, query);
}
/*
* @Author lenient
* @explain 删除索引
* @Date 15:41 2021/5/19
* @Description
* @Param [index(索引)]
* @return boolean
**/
public static ResultBean deleteIndex(String index){
Request request=new Request("DELETE",index);
try {
Response response =client.performRequest(request);
int statusCode = response.getStatusLine().getStatusCode();
String str = EntityUtils.toString(response.getEntity());
return ResultBean.succees(statusCode,"true",str);
} catch (IOException e) {
return ResultBean.error(e);
}
}
/*
* @Author lenient
* @explain 根据id删除数据
* @Date 16:38 2021/5/19
* @Description
* @Param [index(索引), type(类型), id(正id _id)]
* @return boolean
**/
public static ResultBean delectableDataById(String index, String type,String id){
try {
Request request= new Request("DELETE",
new StringBuilder("/")
.append(index).append("/")
.append(type).append("/")
.append(id).toString()
);
Response response=client.performRequest(request);
// 获取状态码
int statusCode = response.getStatusLine().getStatusCode();
String str = EntityUtils.toString(response.getEntity());
return ResultBean.succees(statusCode,"true",str);
} catch (IOException e) {
return ResultBean.error(e);
}
}
/*
* @Author lenient
* @explain 添加数据 如果索引不存在则创建索引,如果id存在则修改数据
* @Date 16:09 2021/5/19
* @Description
* @Param [jsonObject(要添加的数据), index(索引), type(类型), id(正id _id)]
* @return java.lang.String
**/
public static ResultBean addData(JSONObject jsonObject, String index, String type, String id){
try { //构造HTTP请求
Request request;
if(StringUtils.isBlank(id)){
request = new Request("POST", //请求类型
// 不指定_id 会自动生成_id
new StringBuilder("/"+index+"/"+type+"/").toString());
}else {
request = new Request("POST", //请求类型
// /索引/类型 /_index/_type/ 索引名称必须小写 否则会报错
new StringBuilder("/"+index+"/"+type+"/")
//拼接_id 如果_id存在则修改数据,不存在添加数据
.append(id).toString());
}
//添加 优化json返回类型
request.addParameter("pretty","true");
//将json字符HttpEntity类型 并指定类型
NStringEntity nStringEntity = new NStringEntity(jsonObject.toString(), ContentType.APPLICATION_JSON);
//添加数据
request.setEntity(nStringEntity);
//发送HTTP请求 performRequest是同步的,将阻塞调用线程并在请求成功时返回Response
Response response = client.performRequest(request);
int statusCode = response.getStatusLine().getStatusCode();
String str = EntityUtils.toString(response.getEntity());
return ResultBean.succees(statusCode,"true",str);
} catch (IOException e) {
return ResultBean.error(e);
}
}
/*
* @Author lenient
* @explain 添加数据 会自动生成_id, 如果索引不存在则创建索引
* @Date 16:12 2021/5/19
* @Description
* @Param [jsonObject(要添加的数据), index(索引), type(类型)]
* @return java.lang.String
**/
public static ResultBean addData(JSONObject jsonObject, String index, String type){
String id=null;
return addData(jsonObject,index,type,id);
}
/*
* @Author lenient
* @explain 根据索引查询所有数据
* @Date 20:06 2021/5/19
* @Description
* @Param [index(索引), type(类型),maxResult(最大查询数)]
* @return com.alibaba.fastjson.JSONArray
**/
public static ResultBean queryDataAll(String index, String type,int maxResult){
JSONArray jsonArray=new JSONArray();
String str = "{\"query\":{\"match_all\":{}}}";
ResultBean result = queryDataCount(index, type, str);
int total;
if(200 == result.getCode()){
total = Integer.parseInt(result.getData().toString());
if(total>maxResult){
return ResultBean.error("查询数据为"+total+"条,大于【maxResult】最大值"+maxResult+"条,建议优化查询条件,或设置索引库【max_result_Window】");
}else{
str = "{\"query\":{\"match_all\":{}},\"size\":"+total+"}";
}
}else {
return result;
}
try {
//构建HTTP 请求
Request request=new Request("GET",
new StringBuilder("/"+index+"/"+type+"/_search").toString()
);
//添加 优化json返回类型 会添加换行符 可要可不要
request.addParameter("pretty","true");
//构建查询体
NStringEntity nStringEntity=new NStringEntity(str,ContentType.APPLICATION_JSON);
//添加数据
request.setEntity(nStringEntity);
//发送HTTP请求 performRequest是同步的,将阻塞调用线程并在请求成功时返回Response
Response response = client.performRequest(request);
int statusCode = response.getStatusLine().getStatusCode();
String string = EntityUtils.toString(response.getEntity());
JSONObject jsonObject = JSONObject.parseObject(string);
JSONObject hits = jsonObject.getJSONObject("hits");
JSONArray hitsArray = hits.getJSONArray("hits");
for (Object obj :hitsArray){
Object source = ((JSONObject) obj).get("_source");
jsonArray.add(source);
}
return ResultBean.succees(statusCode,total+"条", jsonArray);
} catch (IOException e) {
return ResultBean.error(e);
}
}
/*
* @Author lenient
* @explain 查询所有数据
* @Date 15:44 2021/5/20
* @Description
* @Param [index(索引), type(类型)]
* @return com.lenient.ybg.baseBean.ResultBean
**/
public static ResultBean queryDataAll(String index, String type){
return queryDataAll( index, type,10000);
}
/*
* @Author lenient
* @explain 根据id查询数据
* @Date 20:20 2021/5/19
* @Description
* @Param [index(索引), type(类型), id(正id _id)]
* @return java.lang.Object
**/
public static ResultBean queryDataById(String index,String type,String id){
try{
Request request=new Request("GET",new StringBuilder("/")
.append(index).append("/")
.append(type).append("/")
.append(id).toString());
Response response=client.performRequest(request);
JSONObject jsonObject1 = JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
Object object = jsonObject1.get("_source");
return ResultBean.succees(object);
} catch (IOException e) {
return ResultBean.error(e);
}
}
/*
* @Author lenient
* @explain 根据查询体组合查询
* @Date 20:37 2021/5/19
* @Description
* @Param [index(索引), type(类型), query(查询体), maxResult(最大查询数)]
* @return com.alibaba.fastjson.JSONArray
**/
public static ResultBean queryDataGroup(String index,String type,String query,int maxResult){
JSONArray jsonArray=new JSONArray();
ResultBean result = queryDataCount(index, type, query);
int total;
if(200 == result.getCode()){
total = Integer.parseInt(result.getData().toString());
if(total>maxResult){
return ResultBean.error("查询数据为"+total+"条,大于【maxResult】大值"+maxResult+"条,建议优化查询条件,或设置索引库【max_result_Window】");
}else{
StringBuilder stringBuilder = new StringBuilder(query.substring(0, query.length() - 1));
query= stringBuilder.append(",\"size\":").append(total).append("}").toString();
}
}else {
return result;
}
try {
Request request=new Request("GET",
new StringBuilder("/"+index+"/"+type+"/_search").toString());
//添加 优化json返回类型
request.addParameter("pretty","true");
//将json字符HttpEntity类型 并指定类型
NStringEntity nStringEntity = new NStringEntity(query, ContentType.APPLICATION_JSON);
//添加数据
request.setEntity(nStringEntity);
//发送HTTP请求 performRequest是同步的,将阻塞调用线程并在请求成功时返回Response
Response response = client.performRequest(request);
int statusCode = response.getStatusLine().getStatusCode();
String string = EntityUtils.toString(response.getEntity());
JSONObject jsonObject = JSONObject.parseObject(string);
JSONObject hits = jsonObject.getJSONObject("hits");
JSONArray hitsArray = hits.getJSONArray("hits");
for (Object obj :hitsArray){
Object source = ((JSONObject) obj).get("_source");
jsonArray.add(source);
}
return ResultBean.succees(statusCode, total+"条",jsonArray);
}catch (Exception e){
return ResultBean.error(e);
}
}
/*
* @Author lenient
* @explain 根据查询体组合查询
* @Date 15:42 2021/5/20
* @Description
* @Param [index(索引), type(类型), query(查询体)]
* @return com.lenient.ybg.baseBean.ResultBean
**/
public static ResultBean queryDataGroup(String index,String type,String query){
return queryDataGroup( index, type, query,10000);
}
/**
* @Author lenient
* @explain 查询数据总条数
* @Date 18:03 2021/5/20
* @Description
* @Param [index(索引), type(类型), query(查询体)]
* @return com.lenient.ybg.baseBean.ResultBean
**/
public static ResultBean queryDataCount(String index,String type,String query){
try {
Request request=new Request("GET",
new StringBuilder("/"+index+"/"+type+"/_count").toString());
if(StringUtils.isNotBlank(query)){
//将json字符HttpEntity类型 并指定类型
NStringEntity nStringEntity = new NStringEntity(query, ContentType.APPLICATION_JSON);
//添加数据
request.setEntity(nStringEntity);
}
//发送HTTP请求 performRequest是同步的,将阻塞调用线程并在请求成功时返回Response
Response response = client.performRequest(request);
int statusCode = response.getStatusLine().getStatusCode();
String string = EntityUtils.toString(response.getEntity());
JSONObject jsonObject = JSONObject.parseObject(string);
String count = jsonObject.getString("count");
return ResultBean.succees("成功",count);
}catch (Exception e){
return ResultBean.error(e);
}
}
/**
* @Author lenient
* @explain 分页查询
* @Date 18:14 2021/5/20
* @Description
* @Param [index(索引), type(类型), query(查询体), size(条数), from(页码)]
* @return com.lenient.ybg.baseBean.ResultBean
**/
public static ResultBean pagingQueryData(String index,String type,String query,int size,int from){
JSONArray jsonArray=new JSONArray();
try {
StringBuilder stringBuilder = new StringBuilder(query.substring(0, query.length() - 1));
query= stringBuilder.append(",\"size\":").append(size)
.append(",\"from\":").append(from)
.append("}").toString();
Request request=new Request("GET",
new StringBuilder("/"+index+"/"+type+"/_search").toString());
//添加 优化json返回类型
request.addParameter("pretty","true");
//将json字符HttpEntity类型 并指定类型
NStringEntity nStringEntity = new NStringEntity(query, ContentType.APPLICATION_JSON);
//添加数据
request.setEntity(nStringEntity);
//发送HTTP请求 performRequest是同步的,将阻塞调用线程并在请求成功时返回Response
Response response = client.performRequest(request);
int statusCode = response.getStatusLine().getStatusCode();
String string = EntityUtils.toString(response.getEntity());
JSONObject jsonObject = JSONObject.parseObject(string);
JSONObject hits = jsonObject.getJSONObject("hits");
JSONArray hitsArray = hits.getJSONArray("hits");
if(hitsArray.size()>0){
for (Object obj :hitsArray){
Object source = ((JSONObject) obj).get("_source");
jsonArray.add(source);
}
}
return ResultBean.succees(statusCode, jsonArray);
}catch (Exception e){
return ResultBean.error(e);
}
}
}
**
5.代码测试
**
package com.lenient.ybg.controller;
import com.lenient.ybg.baseBean.ResultBean;
import com.lenient.ybg.config.ES.EsUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @ClassName EsTest
* @author: Lenient
* @date: 2021/5/19 11:03
* @description:
* @explain
*/
@RestController
@RequestMapping("/es/test")
public class EsTest {
@RequestMapping("/add")
public ResultBean add(){
String str = "{\"name\":\"张三\"}";
String query1="{\"settings\":{\"number_of_shards\" : 1,\n" +
" \"number_of_replicas\" : 0}}";
String query="{\n" +
" \"query\": {\n" +
" \"match_all\": {}\n" +
" }\n" +
"}";
//添加数据指定id
//ResultBean resultBean = EsUtils.addData(JSON.parseObject(str), "haa-hh", "index", "123");
//添加数据不指定id
//ResultBean resultBean = EsUtils.addData(JSON.parseObject(str), "haa-hh", "index");
//根据id删除数据
//ResultBean Bean resultBean = EsUtils.delectableDataById("haa-hh", "index", "123");
//删除索引
//ResultBean resultBean = EsUtils.deleteIndex("haa-hh");
//判断索引是否存在
//ResultBean resultBean = EsUtils.isIndexExist("haa-hh");
//创建索引1
//ResultBean resultBean=EsUtils.createIndex("haa-hh");
//创建索引2
//ResultBean resultBean =EsUtils.createIndex("haa-hh",query1);
//查询数据
//ResultBean resultBean = EsUtils.queryDataAll("haa-hh", "index");
//根据id查询数据
//ResultBean resultBean = EsUtils.queryDataById("haa-hh", "info","35");
//条件查询
//ResultBean resultBean = EsUtils.queryDataGroup("haa-hh", "info",query);
//查询数据量
//ResultBean resultBean = EsUtils.queryDataCount("haa-hh", "info",query);
//分页查询
ResultBean resultBean = EsUtils.pagingQueryData("haa-hh", "index", query, 3, 2);
return resultBean;
}
}