1.引入依赖
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.4.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.49</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
2.获取client 连接
以下方式,为了提供测试使用,ip可通过配置文件获取,使用Spring架构,可将ESClientFactory声明为配置类,将RestHighLevelClient通过@Bean注入到容器使用
// 参考 https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.4/java-rest-high-getting-started-initialization.html
public class ESClientFactory {
public static RestHighLevelClient getClient() {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("127.0.0.1", 9200, "http")));
return client;
}
}
3. 简单封装ESManage,支持索引的增删改查,批量操作、根据需求选择同步或异步执行
package com.jiwei.coding_elasticsearch.core;
import com.alibaba.fastjson.JSONObject;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.bulk.*;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.print.attribute.standard.ReferenceUriSchemesSupported;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.BiConsumer;
/**
* es索引管理,索引的增删改查、批量操作、根据需求选择同步或异步执行
*
* @author zhaojiwei
* @date 2019/4/9
*/
public class ESManage {
private final static RestHighLevelClient client = ESClientFactory.getClient();
private static Logger logger = LoggerFactory.getLogger(ESManage.class);
/**
* 根据索引名称程创建索引
*
* @param indexName 索引名称
*/
public static void createIndex(String indexName) {
CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
try {
CreateIndexResponse response = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
System.out.println(response.index());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 索引文档
* request 有很多的配置项可进行设置(routing、parent、timeout等) ; response 正常和异常的处理,版本冲突等
* 参考 https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.4/java-rest-high-document-index.html
*
* @param indexName 索引名称
* @param type 类型
* @param id 自定义id (id为空时默认自动生成)
* @param jsonString 文档
*/
public static void indexRequest(String indexName, String type, String id, String jsonString) {
IndexRequest request = new IndexRequest(indexName, type, id);
request.source(jsonString, XContentType.JSON);
try {
// 同步请求方式
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
System.out.println(indexResponse.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 索引文档
*
* @param indexName 索引名称
* @param type 类型
* @param id 自定义id (id为空时默认自动生成)
* @param map 文档
*/
public static void indexRequest(String indexName, String type, String id, Map<String, Object> map) {
IndexRequest request = new IndexRequest(indexName, type, id);
request.source(map);
try {
// 同步请求方式
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
System.out.println(indexResponse.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 索引文档(异步执行)
*
* @param indexName 索引名称
* @param type 类型
* @param id 自定义id
* @param jsonString 文档
*/
public static void indexRequestAsync(String indexName, String type, String id, String jsonString) {
IndexRequest request = new IndexRequest(indexName, type, id);
request.source(jsonString, XContentType.JSON);
ActionListener<IndexResponse> listener = new ActionListener<IndexResponse>() {
@Override
public void onResponse(IndexResponse indexResponse) {
// 成功响应
System.out.println("响应成功:" + indexResponse.toString());
}
@Override
public void onFailure(Exception e) {
// 异常处理
}
};
// 异步请求方式,异步方法不会阻塞并立即返回
client.indexAsync(request, RequestOptions.DEFAULT, listener);
}
/**
* 根据文档id获取文档
* 参考 https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.4/java-rest-high-document-get.html
* response eg: {"_index":"test123","_type":"test123","_id":"1","_version":1,"found":true,"_source":{"name":"张三","age":123}}
*
* @param indexName 索引名称
* @param type 类型
* @param id 文档id
*/
public static void getRequest(String indexName, String type, String id) {
GetRequest request = new GetRequest(indexName, type, id);
//request.fetchSourceContext(FetchSourceContext.DO_NOT_FETCH_SOURCE);
//request.refresh(true); // 每次查询前刷新索引,ops大的情况下不建议使用
//request.realtime();
//request.routing();
try {
GetResponse response = client.get(request, RequestOptions.DEFAULT);
// 异步方式
//client.getAsync(request,RequestOptions.DEFAULT, listener);
System.out.println(response.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 判断文档是否存在
* 参考 https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.4/java-rest-high-document-exists.html
*
* @param indexName 索引名称
* @param type 类型
* @param id 文档id
* @return
*/
public static boolean exists(String indexName, String type, String id) {
GetRequest request = new GetRequest(indexName, type, id);
request.fetchSourceContext(new FetchSourceContext(false));
request.storedFields("_none_");
boolean exists = false;
try {
exists = client.exists(request, RequestOptions.DEFAULT);
// 异步方式
//client.existsAsync(getRequest, RequestOptions.DEFAULT, listener);
} catch (IOException e) {
e.printStackTrace();
}
return exists;
}
/**
* 根据文档id删除文档
* 参考 https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.4/java-rest-high-document-delete.html
* DeleteResponse继承于DocWriteResponse
*
* @param indexName 索引名称
* @param type 类型
* @param id 文档id
*/
public static void deleteRequest(String indexName, String type, String id) {
DeleteRequest request = new DeleteRequest(indexName, type, id);
try {
DeleteResponse deleteResponse = client.delete(request, RequestOptions.DEFAULT);
System.out.println(deleteResponse.toString());
// 异步方式
// client.deleteAsync(request, RequestOptions.DEFAULT, listener);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 变更文档,支持局部更新
* 参考 https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.4/java-rest-high-document-update.html
*
* @param indexName 索引名称
* @param type 类型
* @param id 文档id
* @param jsonString
*/
public static void updateRequest(String indexName, String type, String id, String jsonString) {
UpdateRequest request = new UpdateRequest(indexName, type, id);
request.doc(jsonString, XContentType.JSON);
// 文档存在则更新,反之创建
request.docAsUpsert(true);
try {
UpdateResponse updateResponse = client.update(request, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 变更文档,支持局部更新
*
* @param indexName 索引名称
* @param type 索引类型
* @param id 文档id
* @param map
*/
public static void updateRequest(String indexName, String type, String id, Map<String, Object> map) {
UpdateRequest request = new UpdateRequest(indexName, type, id);
request.doc(map);
request.docAsUpsert(true);
try {
UpdateResponse updateResponse = client.update(request, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* bulk 批量操作
* 参考 https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.4/java-rest-high-document-bulk.html
*
* @param indexName 索引名称
* @param type 类型
* @param id 文档id
* @param jsonString
* @param opType 操作类型(1 index/ 2 update/ 3 delete)
*/
public static void bulkRequest(String indexName, String type, String id, String jsonString, int opType) {
BulkRequest request = new BulkRequest();
switch (opType) {
case 1:
request.add(new IndexRequest(indexName, type, id).source(jsonString, XContentType.JSON));
break;
case 2:
request.add(new UpdateRequest(indexName, type, id).doc(jsonString, XContentType.JSON));
break;
case 3:
request.add(new DeleteRequest(indexName, type, id));
break;
default:
request.add(new UpdateRequest(indexName, type, id).doc(jsonString, XContentType.JSON));
}
try {
BulkResponse bulkResponse = client.bulk(request, RequestOptions.DEFAULT);
// 异步方式
// client.bulkAsync(request, RequestOptions.DEFAULT, listener);
/**
* 获取响应方式一
*/
// for (BulkItemResponse bulkItemResponse : bulkResponse) {
// DocWriteResponse itemResponse = bulkItemResponse.getResponse();
//
// if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.INDEX
// || bulkItemResponse.getOpType() == DocWriteRequest.OpType.CREATE) {
// IndexResponse indexResponse = (IndexResponse) itemResponse;
//
// } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.UPDATE) {
// UpdateResponse updateResponse = (UpdateResponse) itemResponse;
//
// } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.DELETE) {
// DeleteResponse deleteResponse = (DeleteResponse) itemResponse;
// }
// }
/**
* 获取响应方式二
*/
for (BulkItemResponse bulkItemResponse : bulkResponse) {
if (bulkItemResponse.isFailed()) {
BulkItemResponse.Failure failure = bulkItemResponse.getFailure();
System.out.println(failure.toString());
// 获取失败的 索引 索引type 文档id
System.out.println(failure.getIndex() + " " + failure.getType() + " " + failure.getId());
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* bulkProcessor 批量操作
* 参考 https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.4/java-rest-high-document-bulk.html
*
* @param indexName 索引名称
* @param type 类型
* @param id 文档id
* @param jsonString
* @param opType 操作类型(1 index/ 2 update/ 3 delete)
*/
public static void bulkProcessor(String indexName, String type, String id, String jsonString, int opType) {
BulkProcessor.Listener listener = new BulkProcessor.Listener() {
@Override
public void beforeBulk(long executionId, BulkRequest request) {
}
@Override
public void afterBulk(long executionId, BulkRequest request,
BulkResponse response) {
if (response.hasFailures()) {
logger.error("Bulk [{}] executed with failures,failtrueMessage: {} ", executionId, response.buildFailureMessage());
}
}
@Override
public void afterBulk(long executionId, BulkRequest request, Throwable failure) {
logger.error("Failed to execute bulk", failure);
}
};
BiConsumer<BulkRequest, ActionListener<BulkResponse>> bulkConsumer =
(request, bulkListener) -> client.bulkAsync(request, RequestOptions.DEFAULT, bulkListener);
BulkProcessor.Builder builder = BulkProcessor.builder(bulkConsumer, listener);
// 操作数达到1000个时进行刷新操作,默认1000,-1 禁用
builder.setBulkActions(1000);
// 操作数大小达到5M进行刷新操作,默认 5Mb,-1禁用
builder.setBulkSize(new ByteSizeValue(5L, ByteSizeUnit.MB));
// 设置允许执行的并发请求数 默认为 1,0允许执行单个请求
builder.setConcurrentRequests(1);
// 设置flush间隔时间
builder.setFlushInterval(TimeValue.timeValueSeconds(10L));
// 后退策略
builder.setBackoffPolicy(BackoffPolicy
.constantBackoff(TimeValue.timeValueSeconds(1L), 3));
switch (opType) {
case 1:
builder.build().add(new IndexRequest(indexName, type, id).source(jsonString, XContentType.JSON));
break;
case 2:
builder.build().add(new UpdateRequest(indexName, type, id).doc(jsonString, XContentType.JSON));
break;
case 3:
builder.build().add(new DeleteRequest(indexName, type, id));
break;
default:
builder.build().add(new UpdateRequest(indexName, type, id).doc(jsonString, XContentType.JSON));
}
}
public static void main(String[] args) {
// 测试示例
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", "zhangsan");
jsonObject.put("age", 99);
jsonObject.put("hobby", "篮球");
jsonObject.put("appName", "estest");
jsonObject.put("content", "conent test conent test conent test conent test conent test conent test conent test conent test ");
ESManage.bulkProcessor("test123", "test123", "4", jsonObject.toJSONString(), 1);
}
}