本文原始碼: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·點這裡 | ☆☆☆☆☆ |