@Component
public class ESUtil {
private final static Logger LOGGER = LoggerFactory.getLogger(ESUtil.class);
private static RestHighLevelClient client = null;
/**
* esConfig为通过配置文件获取 es的配置信息,从init()方法中可以反向推出其代码
* 此处就不共享了
**/
@Autowired
ESConfig esConfig;
private static String PROTOCOL = "http";
@PostConstruct
private void init(){
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(esConfig.getUsername(), esConfig.getPassword()));
List<HttpHost> hosts = new ArrayList<>();
esConfig.getIp().forEach(ip -> {
String[] ipPort = ip.split(":");
hosts.add(new HttpHost(ipPort[0], Integer.parseInt(ipPort[1]), PROTOCOL));
});
client = new RestHighLevelClient(
RestClient.builder(hosts.toArray(new HttpHost[hosts.size()]))
.setHttpClientConfigCallback(
new RestClientBuilder.HttpClientConfigCallback() {
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
httpClientBuilder.disableAuthCaching();
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
})
);
}
/**
* 保存/更新数据
* @param index 索引(库)
* @param type 类型 (表)
* @param id 唯一主键(表数据id)
* @param obj 数据
* @return 执行状态 OK 成功 INTERNAL_SERVER_ERROR 失败
*/
public static RestStatus upsert(String index, String id, Object obj) {
try {
UpdateRequest updateRequest = new UpdateRequest(index, id)
.doc(JacksonUtils.toJsonString(obj),XContentType.JSON)
.docAsUpsert(true);
UpdateResponse response = client.update(updateRequest,RequestOptions.DEFAULT);
return response.status();
} catch (Exception e) {
LOGGER.error("insert data is failed: ",e);
}
return RestStatus.INTERNAL_SERVER_ERROR;
}
/**
* 批量插入 实体中必须含有id字段
* @param index 索引(库)
* @param type 类型 (表)
* @param objects 实体数据
* @return 执行状态 OK 成功 INTERNAL_SERVER_ERROR 失败
* @throws IOException 异常
*/
public static RestStatus batchUpsert(String index, List<?> objects) throws IOException {
try {
BulkRequest bulkRequest = new BulkRequest();
BulkResponse response = null;
String id = null;
for (Object object : objects) {
ObjectNode jsonObject = JacksonUtils.toObjectNode(object);
if (!jsonObject.has("id")) {
LOGGER.error("data of batch upserted is not contain `id`", jsonObject.toString());
return RestStatus.INTERNAL_SERVER_ERROR;
}
id = jsonObject.get("id").asText();
buildBuldRequest(index, bulkRequest, id, jsonObject.toString());
}
response = client.bulk(bulkRequest, RequestOptions.DEFAULT);
return RestStatus.OK;
}catch (Exception e){
LOGGER.error("batch insert error:", e);
return RestStatus.INTERNAL_SERVER_ERROR;
}
}
/**
* 构建 批量 request
* @param index
* @param type
* @param bulkRequest
* @param id
* @param jsonObject
* @throws IOException
*/
private static void buildBuldRequest(String index, BulkRequest bulkRequest, String id, String jsonObject) throws IOException {
UpdateRequest updateRequest = new UpdateRequest(index, id)
.doc(jsonObject,XContentType.JSON)
.docAsUpsert(true);
bulkRequest.add(updateRequest);
}
/**
* 异步批量插入 实体中必须含有id字段(总条数不得超过20W)
* @param index 索引(库)
* @param type 类型 (表)
* @param objects 实体数据
* @throws IOException 异常
*/
public static void batchUpsertAsync(String index, List<?> objects) throws IOException {
BulkRequest bulkRequest = new BulkRequest();
//最大数量不得超过20万
for (Object object: objects) {
ObjectNode jsonObject = JacksonUtils.toObjectNode(object);
if (!jsonObject.has("id")) {
throw new BusinessException("data of batch upserted is not contain `id` : " + jsonObject.toString());
}
String id = jsonObject.get("id").asText();
buildBuldRequest(index, bulkRequest, id, jsonObject.toString());
}
client.bulkAsync(bulkRequest, RequestOptions.DEFAULT,new ActionListener<BulkResponse>() {
@Override
public void onResponse(BulkResponse bulkItemResponses) {
LOGGER.info(bulkItemResponses.buildFailureMessage());
}
@Override
public void onFailure(Exception e) {
LOGGER.error("batch upsert error:", e);
}
});
}
/**
* 查询
* @param index 索引(库)
* @param searchSourceBuilder searchSourceBuilder
* @return SearchResponse
* @throws IOException 异常
*/
public static SearchResponse search(String index, SearchSourceBuilder searchSourceBuilder) throws IOException {
searchSourceBuilder.timeout(new TimeValue(1, TimeUnit.MINUTES));
if(searchSourceBuilder.size() < 1){
searchSourceBuilder.size(100);
}
SearchRequest searchRequest = new SearchRequest(index);
searchRequest.source(searchSourceBuilder);
return client.search(searchRequest, RequestOptions.DEFAULT);
}
}