本文源碼:GitHub·點這里 || GitEE·點這里
一、基礎API簡介
1、RestHighLevelClient
RestHighLevelClient的API作為ElasticSearch備受推薦的客戶端組件,其封裝系統操作ES的方法,包括索引結構管理,數據增刪改查管理,常用查詢方法,並且可以結合原生ES查詢原生語法,功能十分強大。
在使用RestHighLevelClient的語法時,通常涉及上面幾個方面,在掌握基礎用法之上可以根據業務特點進行一些自定義封裝,這樣可以更優雅的解決業務需求。
2、核心依賴
使用RestHighLevelClient需要依賴rest-high-level-client
包,和ES相關基礎依賴。
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
二、索引管理
這里不做過多描述,注意一點:因為ES的數據結構特點,所以不需要索引更新方法,新的字段在更新數據時直接寫入即可,不需要提前更新索引結構。
@Service
public class EsIndexOperation {
@Resource
private RestHighLevelClient client ;
private final RequestOptions options = RequestOptions.DEFAULT;
/**
* 判斷索引是否存在
*/
public boolean checkIndex (String index) {
try {
return client.indices().exists(new GetIndexRequest(index), options);
} catch (IOException e) {
e.printStackTrace();
}
return Boolean.FALSE ;
}
/**
* 創建索引
*/
public boolean createIndex (String indexName ,Map<String, Object> columnMap){
try {
if(!checkIndex(indexName)){
CreateIndexRequest request = new CreateIndexRequest(indexName);
if (columnMap != null && columnMap.size()>0) {
Map<String, Object> source = new HashMap<>();
source.put("properties", columnMap);
request.mapping(source);
}
this.client.indices().create(request, options);
return Boolean.TRUE ;
}
} catch (IOException e) {
e.printStackTrace();
}
return Boolean.FALSE;
}
/**
* 刪除索引
*/
public boolean deleteIndex(String indexName) {
try {
if(checkIndex(indexName)){
DeleteIndexRequest request = new DeleteIndexRequest(indexName);
AcknowledgedResponse response = client.indices().delete(request, options);
return response.isAcknowledged();
}
} catch (Exception e) {
e.printStackTrace();
}
return Boolean.FALSE;
}
}
三、數據管理
這里在更新數據時,可以直接修改索引結構,在dataMap中放進新的字段即可。
@Service
public class EsDataOperation {
@Resource
private RestHighLevelClient client ;
private final RequestOptions options = RequestOptions.DEFAULT;
/**
* 寫入數據
*/
public boolean insert (String indexName, Map<String,Object> dataMap){
try {
BulkRequest request = new BulkRequest();
request.add(new IndexRequest(indexName,"doc").id(dataMap.remove("id").toString())
.opType("create").source(dataMap,XContentType.JSON));
this.client.bulk(request, options);
return Boolean.TRUE ;
} catch (Exception e){
e.printStackTrace();
}
return Boolean.FALSE;
}
/**
* 批量寫入數據
*/
public boolean batchInsert (String indexName, List<Map<String,Object>> userIndexList){
try {
BulkRequest request = new BulkRequest();
for (Map<String,Object> dataMap:userIndexList){
request.add(new IndexRequest(indexName,"doc").id(dataMap.remove("id").toString())
.opType("create").source(dataMap,XContentType.JSON));
}
this.client.bulk(request, options);
return Boolean.TRUE ;
} catch (Exception e){
e.printStackTrace();
}
return Boolean.FALSE;
}
/**
* 更新數據,可以直接修改索引結構
*/
public boolean update (String indexName, Map<String,Object> dataMap){
try {
UpdateRequest updateRequest = new UpdateRequest(indexName,"doc", dataMap.remove("id").toString());
updateRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
updateRequest.doc(dataMap) ;
this.client.update(updateRequest, options);
return Boolean.TRUE ;
} catch (Exception e){
e.printStackTrace();
}
return Boolean.FALSE;
}
/**
* 刪除數據
*/
public boolean delete (String indexName, String id){
try {
DeleteRequest deleteRequest = new DeleteRequest(indexName,"doc", id);
this.client.delete(deleteRequest, options);
return Boolean.TRUE ;
} catch (Exception e){
e.printStackTrace();
}
return Boolean.FALSE;
}
}
四、查詢操作
注意:查詢總數的CountRequest語法,SearchRequest查詢結果中數據轉換語法,分頁查詢中需要指定偏移位置和分頁大小。
@Service
public class EsQueryOperation {
@Resource
private RestHighLevelClient client ;
private final RequestOptions options = RequestOptions.DEFAULT;
/**
* 查詢總數
*/
public Long count (String indexName){
// 指定創建時間
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
queryBuilder.must(QueryBuilders.termQuery("createTime", 1611378102795L));
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(queryBuilder);
CountRequest countRequest = new CountRequest(indexName);
countRequest.source(sourceBuilder);
try {
CountResponse countResponse = client.count(countRequest, options);
return countResponse.getCount();
} catch (Exception e) {
e.printStackTrace();
}
return 0L;
}
/**
* 查詢集合
*/
public List<Map<String,Object>> list (String indexName) {
// 查詢條件,指定時間並過濾指定字段值
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
queryBuilder.must(QueryBuilders.termQuery("createTime", 1611378102795L));
queryBuilder.mustNot(QueryBuilders.termQuery("name","北京-李四"));
sourceBuilder.query(queryBuilder);
SearchRequest searchRequest = new SearchRequest(indexName);
searchRequest.source(sourceBuilder);
try {
SearchResponse searchResp = client.search(searchRequest, options);
List<Map<String,Object>> data = new ArrayList<>() ;
SearchHit[] searchHitArr = searchResp.getHits().getHits();
for (SearchHit searchHit:searchHitArr){
Map<String,Object> temp = searchHit.getSourceAsMap();
temp.put("id",searchHit.getId()) ;
data.add(temp);
}
return data;
} catch (Exception e) {
e.printStackTrace();
}
return null ;
}
/**
* 分頁查詢
*/
public List<Map<String,Object>> page (String indexName,Integer offset,Integer size) {
// 查詢條件,指定時間並過濾指定字段值
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.from(offset);
sourceBuilder.size(size);
sourceBuilder.sort("createTime", SortOrder.DESC);
SearchRequest searchRequest = new SearchRequest(indexName);
searchRequest.source(sourceBuilder);
try {
SearchResponse searchResp = client.search(searchRequest, options);
List<Map<String,Object>> data = new ArrayList<>() ;
SearchHit[] searchHitArr = searchResp.getHits().getHits();
for (SearchHit searchHit:searchHitArr){
Map<String,Object> temp = searchHit.getSourceAsMap();
temp.put("id",searchHit.getId()) ;
data.add(temp);
}
return data;
} catch (Exception e) {
e.printStackTrace();
}
return null ;
}
}
五、排序方式
排序除了常規的指定字段升序降序規則之外,還可以基於原生的腳本語法,基於自定義規則排序讓一些特定的數據沉底或者置頂。
@Service
public class EsSortOperation {
@Resource
private RestHighLevelClient client ;
private final RequestOptions options = RequestOptions.DEFAULT;
/**
* 排序規則
*/
public List<Map<String,Object>> sort (String indexName) {
// 先升序時間,在倒序年齡
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.sort("createTime", SortOrder.ASC);
sourceBuilder.sort("age",SortOrder.DESC) ;
SearchRequest searchRequest = new SearchRequest(indexName);
searchRequest.source(sourceBuilder);
try {
SearchResponse searchResp = client.search(searchRequest, options);
List<Map<String,Object>> data = new ArrayList<>() ;
SearchHit[] searchHitArr = searchResp.getHits().getHits();
for (SearchHit searchHit:searchHitArr){
Map<String,Object> temp = searchHit.getSourceAsMap();
temp.put("id",searchHit.getId()) ;
data.add(temp);
}
return data;
} catch (Exception e) {
e.printStackTrace();
}
return null ;
}
/**
* 自定義排序規則
*/
public List<Map<String,Object>> defSort (String indexName) {
// 指定置換順序的規則
// [age 12-->60]\[age 19-->10]\[age 13-->30]\[age 18-->40],age其他值忽略為1
Script script = new Script("def _ageSort = doc['age'].value == 12?60:" +
"(doc['age'].value == 19?10:" +
"(doc['age'].value == 13?30:" +
"(doc['age'].value == 18?40:1)));" + "_ageSort;");
ScriptSortBuilder sortBuilder = SortBuilders.scriptSort(script,ScriptSortBuilder.ScriptSortType.NUMBER);
sortBuilder.order(SortOrder.ASC);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.sort(sortBuilder);
SearchRequest searchRequest = new SearchRequest(indexName);
searchRequest.source(sourceBuilder);
try {
SearchResponse searchResp = client.search(searchRequest, options);
List<Map<String,Object>> data = new ArrayList<>() ;
SearchHit[] searchHitArr = searchResp.getHits().getHits();
for (SearchHit searchHit:searchHitArr){
Map<String,Object> temp = searchHit.getSourceAsMap();
temp.put("id",searchHit.getId()) ;
data.add(temp);
}
return data;
} catch (Exception e) {
e.printStackTrace();
}
return null ;
}
}
六、源代碼地址
GitHub·地址
https://github.com/cicadasmile/data-manage-parent
GitEE·地址
https://gitee.com/cicadasmile/data-manage-parent
推薦閱讀:編程體系整理
序號 | 項目名稱 | GitHub地址 | GitEE地址 | 推薦指數 |
---|---|---|---|---|
01 | Java描述設計模式,算法,數據結構 | GitHub·點這里 | GitEE·點這里 | ☆☆☆☆☆ |
02 | Java基礎、並發、面向對象、Web開發 | GitHub·點這里 | GitEE·點這里 | ☆☆☆☆ |
03 | SpringCloud微服務基礎組件案例詳解 | GitHub·點這里 | GitEE·點這里 | ☆☆☆ |
04 | SpringCloud微服務架構實戰綜合案例 | GitHub·點這里 | GitEE·點這里 | ☆☆☆☆☆ |
05 | SpringBoot框架基礎應用入門到進階 | GitHub·點這里 | GitEE·點這里 | ☆☆☆☆ |
06 | SpringBoot框架整合開發常用中間件 | GitHub·點這里 | GitEE·點這里 | ☆☆☆☆☆ |
07 | 數據管理、分布式、架構設計基礎案例 | GitHub·點這里 | GitEE·點這里 | ☆☆☆☆☆ |
08 | 大數據系列、存儲、組件、計算等框架 | GitHub·點這里 | GitEE·點這里 | ☆☆☆☆☆ |