Elasticsearch 升级之后,发现有很多以前用的API过期了。如elasticRepository中的search方法,ElasticsearchTemplate 等,因此记录一下使用高版本API 操作,并组装了一个简单的工具类供后续使用。
首先是配置文件
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")
// 如果是集群,可以构建多个
/*,new HttpHost("localhost", 9201, "http")*/
)
);
return restHighLevelClient;
}
1、CRUD
我定义了一个CRUD的接口
public interface HignLevelDocumentHandler<T, ID> {
public void save(T t) throws Exception;
public String detail(ID id) throws IOException;
public void update(T t) throws Exception;
public void delete(ID id) throws IOException;
}
其次,实现一个默认的可操作的工具类,在使用前需要将工具类注入Bean,并复制索引名称indexName
/**
* author: ZGF
* context : 默认实现
*/
public class DefaultHignLevelDocumentHandler<T, ID> implements HignLevelDocumentHandler<T, ID> {
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient client;
@Getter
@Setter
private String indexName;
public DefaultHignLevelDocumentHandler(String indexName){
this.indexName = indexName;
}
@Override
public void save(T t) throws Exception {
if (judgeId(t)) {
Field id = t.getClass().getDeclaredField("id");
save(t, id.toString());
return;
}
save(t, null);
}
public void save(T t, String id) throws IOException {
jsonSave(t, id, TimeValue.timeValueSeconds(1));
}
public void jsonSave(T t, String id, TimeValue timeValue) throws IOException {
IndexRequest indexRequest = new IndexRequest(indexName);
indexRequest.id(id);
indexRequest.timeout(timeValue);
indexRequest.source(JSON.toJSONString(t), XContentType.JSON);
client.index(indexRequest, RequestOptions.DEFAULT);
}
@Override
public String detail(ID id) throws IOException {
GetRequest request = new GetRequest(indexName, id.toString());
GetResponse getResponse = client.get(request, RequestOptions.DEFAULT);
return getResponse.getSourceAsString();
}
@Override
public void update(T t) throws Exception {
if (judgeId(t)) {
Field id = t.getClass().getDeclaredField("id");
save(t, id.toString());
} else {
update(t, null);
}
}
public void update(T t, String id) throws Exception {
update(t, id, TimeValue.timeValueSeconds(1));
}
public void update(T t, String id, TimeValue timeValue) throws Exception {
UpdateRequest updateRequest = new UpdateRequest(indexName, id);
updateRequest.timeout(timeValue);
updateRequest.doc(JSON.toJSONString(t), XContentType.JSON);
client.update(updateRequest, RequestOptions.DEFAULT);
}
@Override
public void delete(ID id) throws IOException {
delete(id, TimeValue.timeValueSeconds(1));
}
public void delete(ID id, String timeout) throws IOException {
DeleteRequest deleteRequest = new DeleteRequest(indexName);
deleteRequest.timeout(timeout);
deleteRequest.id(id.toString());
client.delete(deleteRequest, RequestOptions.DEFAULT);
}
public void delete(ID id, TimeValue timeValue) throws IOException {
DeleteRequest deleteRequest = new DeleteRequest(indexName);
deleteRequest.timeout(timeValue);
deleteRequest.id(id.toString());
client.delete(deleteRequest, RequestOptions.DEFAULT);
}
private boolean judgeId(T t){
//获取这个类的所有属性
Field[] fields = t.getClass().getDeclaredFields();
boolean flag = false;
//循环遍历所有的fields
for (int i = 0; i < fields.length; i++) {
if (fields[i].getName().equals("id")) {
flag = true;
break;
}
}
return flag;
}
}
2、批量操作
注意将增删改的Request接口通过add方法进BulkRequest对象,就可以进行批量操作了
@PostMapping("bulk")
public String bulk() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout(TimeValue.timeValueSeconds(10));
ArrayList<Item> items = new ArrayList<>();
items.add(new Item(6L, "狂神说Java", "B站", "爱奇艺", 23D, "b.jpg"));
items.add(new Item(7L, "马保国解说日本萌妹子擂台赛", "Bilibili", "腾讯", 44D, "e.jpg"));
items.add(new Item(8L, "进击的巨人", "Bilibili", "腾讯", 55D, "g.jpg"));
for (int i = 0; i < items.size(); i++) {
bulkRequest.add(new IndexRequest("naga")
// 不指定ID的话,新增时ID是随机的
.id(items.get(i).getId().toString())
.source(JSON.toJSONString(items.get(i)), XContentType.JSON)
);
// bulkRequest.add(UpdateRequest) 批量更新
// bulkRequest.add(DeleteRequest) 批量删除
}
// BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
return "bulk insert OK";
}
3、复杂查询操作
仅仅列举两个最简单的例子,在新版本的API中,查询的组装就像是用代码,来拼接出在kibana上输入的JSON参数一样。
/**
* 分页,条件查询
* @param brandName
* @return
*/
@PostMapping("/get")
public String get(String brandName, int from, int size) throws IOException {
// 条件构造器
SearchSourceBuilder builder = new SearchSourceBuilder();
// 查询构建器 QueryBuilders工具类可以快速构建
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("brand", brandName);
builder.query(matchQueryBuilder);
builder.timeout(TimeValue.timeValueSeconds(10));
/** 分页查询 */
builder.from(from);
builder.size(size);
SearchRequest searchRequest = new SearchRequest("naga");
searchRequest.source(builder);
SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
for (SearchHit temp : result.getHits().getHits()) {
System.out.println(temp.getSourceAsMap());
}
return "query OK";
}
/**
* 查询价格在20以上的
*/
@PostMapping("/range")
public String query() throws IOException {
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
.filter(new RangeQueryBuilder("price").gte(20.0D));
sourceBuilder.query(queryBuilder);
SearchRequest searchRequest = new SearchRequest();
searchRequest.source(sourceBuilder);
SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
for (SearchHit temp : result.getHits().getHits()) {
System.out.println(temp.getSourceAsMap());
}
return "query OK";
}