java RestHighLevelClient方式操作es
之前有寫過一篇文章,介紹使用繼承ElasticsearchRepository類或者使用
ElasticSearchTemplate的方式進行CRUD,但是因為API更新不及時,逐漸不用了。目前還是推薦使用官方的API,即RestHighLevelClient的方式查詢。使用過程中遇到一些坑,記錄下
maven依賴
<dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>${elasticsearch.version}</version> </dependency> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>${elasticsearch.version}</version> </dependency>
使用例子在下面,有兩點需要注意的地方
1.查詢預設會進行分頁,根據業務需要設定返回資料的數量, searchSourceBuilder.size(10000),否則只會返回10條資料
2.本來想用mget提高查詢效率,但是在使用時發現用索引別名查詢的時候,如果是多個索引共用別名會查詢不到資料
package com.example.demo.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import java.io.IOException;
/**
* es配置工廠類
*/
public class ESClientSpringFactory {
public static int CONNECT_TIMEOUT_MILLIS = 1000;
public static int SOCKET_TIMEOUT_MILLIS = 30000;
public static int CONNECTION_REQUEST_TIMEOUT_MILLIS = 500;
public static int MAX_CONN_PER_ROUTE = 10;
public static int MAX_CONN_TOTAL = 30;
private static HttpHost[] HTTP_HOST;
private RestClientBuilder builder;
private RestClient restClient;
private RestHighLevelClient restHighLevelClient;
private static ESClientSpringFactory esClientSpringFactory = new ESClientSpringFactory();
private ESClientSpringFactory(){}
public static ESClientSpringFactory build(HttpHost[] httpHost,
Integer maxConnectNum, Integer maxConnectPerRoute){
HTTP_HOST = httpHost;
MAX_CONN_TOTAL = maxConnectNum;
MAX_CONN_PER_ROUTE = maxConnectPerRoute;
return esClientSpringFactory;
}
public static ESClientSpringFactory build(HttpHost[] httpHost, Integer connectTimeOut, Integer socketTimeOut,
Integer connectionRequestTime, Integer maxConnectNum, Integer maxConnectPerRoute){
HTTP_HOST = httpHost;
CONNECT_TIMEOUT_MILLIS = connectTimeOut;
SOCKET_TIMEOUT_MILLIS = socketTimeOut;
CONNECTION_REQUEST_TIMEOUT_MILLIS = connectionRequestTime;
MAX_CONN_TOTAL = maxConnectNum;
MAX_CONN_PER_ROUTE = maxConnectPerRoute;
return esClientSpringFactory;
}
public void init(){
builder = RestClient.builder(HTTP_HOST);
setConnectTimeOutConfig();
setMutiConnectConfig();
restClient = builder.build();
restHighLevelClient = new RestHighLevelClient(builder);
System.out.println("init factory");
}
// 配置連線時間延時
public void setConnectTimeOutConfig(){
builder.setRequestConfigCallback(requestConfigBuilder -> {
requestConfigBuilder.setConnectTimeout(CONNECT_TIMEOUT_MILLIS);
requestConfigBuilder.setSocketTimeout(SOCKET_TIMEOUT_MILLIS);
requestConfigBuilder.setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT_MILLIS);
return requestConfigBuilder;
});
}
// 使用非同步httpclient時設定併發連線數
public void setMutiConnectConfig(){
builder.setHttpClientConfigCallback(httpClientBuilder -> {
httpClientBuilder.setMaxConnTotal(MAX_CONN_TOTAL);
httpClientBuilder.setMaxConnPerRoute(MAX_CONN_PER_ROUTE);
return httpClientBuilder;
});
}
public RestClient getClient(){
return restClient;
}
public RestHighLevelClient getRhlClient(){
return restHighLevelClient;
}
public void close() {
if (restClient != null) {
try {
restClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("close client");
}
}
package com.example.demo.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
/**
* es配置類
*
* @author : chenpeng36
* @version : 2020/1/15 14:24
*/
@Configuration
public class EsConfiguration {
@Value("${elasticSearch.host}")
private String host;
@Value("${elasticSearch.port}")
private int port;
@Value("${elasticSearch.client.connectNum}")
private Integer connectNum;
@Value("${elasticSearch.client.connectPerRoute}")
private Integer connectPerRoute;
@Bean
public HttpHost[] httpHost() {
String[] array = host.split(",");
HttpHost[] hosts = new HttpHost[array.length];
for (int i = 0; i < array.length; i++) {
hosts[i] = new HttpHost(array[i], port, "http");
}
return hosts;
}
@Bean(initMethod = "init", destroyMethod = "close")
public ESClientSpringFactory getFactory() {
return ESClientSpringFactory.build(httpHost(), connectNum, connectPerRoute);
}
@Bean
@Scope("singleton")
public RestClient getRestClient() {
return getFactory().getClient();
}
@Bean("rhlClient")
@Scope("singleton")
public RestHighLevelClient getRHLClient() {
return getFactory().getRhlClient();
}
}
用的比較多的一個是範圍查詢,一個是精確查詢
package com.example.demo;
import org.elasticsearch.action.get.*;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.Strings;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {DemoApplication.class})
class DemoApplicationTests {
@Autowired
private RestHighLevelClient rhlClient;
//分頁查詢
@Test
public void searchByPage() throws IOException {
//構建搜尋請求物件
SearchRequest searchRequest = new SearchRequest("index_name");
//設定搜尋物件的型別,不需要設定
//searchRequest.types("ads_peer_info_community_type");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
int page = 1;
//每頁記錄數
int size = 2;
//計算出記錄起始下標
int from = (page - 1) * size;
searchSourceBuilder.from(from);//起始記錄下標,從0開始
searchSourceBuilder.size(size);//每頁顯示的記錄數
//搜尋源搜尋方式
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = rhlClient.search(searchRequest, RequestOptions.DEFAULT);
//搜尋結果
SearchHits hits = searchResponse.getHits();
//獲得匹配總記錄
long totalHits = hits.getTotalHits();
System.out.println(totalHits);
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name= (String) sourceAsMap.get("name");
System.out.println(name);
}
}
//mget方式查詢
@Test
public void mgetSearch() throws IOException {
try {
MultiGetRequest request = new MultiGetRequest();
list.forEach(item -> {
request.add(Index, type, item);
});
MultiGetResponse result = restHighLevelClient.mget(request, RequestOptions.DEFAULT);
for (MultiGetItemResponse respons : result.getResponses()) {
if (respons.getResponse()!= null){
Map<String, Object> sourceAsMap = respons.getResponse().getSourceAsMap();
if (sourceAsMap != null) {
InfoEntity infoEntity = new InfoEntity();
Long time = (Long) sourceAsMap.get("time");
String name= (String) sourceAsMap.get("name");
infoEntity.setTime(time);
infoEntity.setName(name);
}
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* 精確搜尋
* 設定搜尋源物件的查詢方式為 termQuery("id","111") 表示查詢欄位為id的關鍵字為111
*
* @throws IOException
*/
@Test
public void termQuery() throws IOException {
//構建搜尋請求物件
SearchRequest searchRequest = new SearchRequest("index");
//設定搜尋物件的型別,不需要設定
//searchRequest.types("type");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termQuery("rowkey", "eb3cddde-f745-4360-bd7c-c271e2087a31"));
//設定源欄位過慮,第一個引數結果集包括哪些欄位,第二個參數列示結果集不包括哪些欄位
// searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","timestamp"},new String[]{});
//向搜尋請求物件中設定搜尋源
searchRequest.source(searchSourceBuilder);
//執行搜尋,向ES發起http請求
SearchResponse searchResponse = rhlClient.search(searchRequest);
//搜尋結果
SearchHits hits = searchResponse.getHits();
//匹配到的總記錄數
long totalHits = hits.getTotalHits();
System.out.println(totalHits);
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String id = (String) sourceAsMap.get("id");
System.out.println(id);
}
}
@Test
public void queryById() throws IOException {
//構建搜尋請求物件
SearchRequest searchRequest = new SearchRequest("index_name");
//設定搜尋物件的型別,不需要設定
//searchRequest.types("type");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//搜尋方式 根據id查詢
String[] ids = new String[]{"d136fc82-f458-4ba2-96a8-e83c4f621571", "6051bcaf-d587-44cd-86ba-b4c5c39da08f"};
searchSourceBuilder.query(QueryBuilders.termsQuery("_id", ids));
//設定源欄位過慮,第一個引數結果集包括哪些欄位,第二個參數列示結果集不包括哪些欄位
// searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","timestamp"},new String[]{});
//向搜尋請求物件中設定搜尋源
searchRequest.source(searchSourceBuilder);
//執行搜尋,向ES發起http請求
SearchResponse searchResponse = rhlClient.search(searchRequest);
//搜尋結果
SearchHits hits = searchResponse.getHits();
//匹配到的總記錄數
long totalHits = hits.getTotalHits();
System.out.println(totalHits);
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String id = (String) sourceAsMap.get("id");
System.out.println(id);
}
}
@Test
public void searchBySingleId() throws IOException {
GetRequest getRequest = new GetRequest("index");
getRequest.id("6051bcaf-d587-44cd-86ba-b4c5c39da08f");
String[] includes = new String[]{"*", "birthday"};
String[] excludes = Strings.EMPTY_ARRAY;
FetchSourceContext fetchSourceContext = new FetchSourceContext(true);
getRequest.fetchSourceContext(fetchSourceContext);
GetResponse response = rhlClient.get(getRequest);
Map<String, Object> sourceAsMap = response.getSourceAsMap();
String id = (String) sourceAsMap.get("id");
System.out.println(id);
System.out.println(response.getSource().keySet().toString());
}
@Test
public void searchByMutiId() throws IOException {
// String[] includes = new String[]{"*", "birthday"};
// String[] excludes = Strings.EMPTY_ARRAY;
FetchSourceContext fetchSourceContext = new FetchSourceContext(true);
MultiGetRequest multiGetRequest = new MultiGetRequest();
multiGetRequest.add(new MultiGetRequest.Item("ads_peer_info_community_index", "ads_peer_info_community_type", "d136fc82-f458-4ba2-96a8-e83c4f621571").fetchSourceContext(fetchSourceContext)); //通過Item新增查詢條件
multiGetRequest.add("ads_peer_info_community_index", "ads_peer_info_community_type", "6051bcaf-d587-44cd-86ba-b4c5c39da08f"); //直接新增查詢條件
MultiGetResponse multiGetItemResponses = rhlClient.multiGet(multiGetRequest);
MultiGetItemResponse[] responses = multiGetItemResponses.getResponses();
for (MultiGetItemResponse response : responses) {
System.out.println(response.getResponse().getSource().keySet().toString());
}
}
//複合條件查詢,時間範圍和精確匹配
@Test
public void test3() {
SearchRequest searchRequest = new SearchRequest(snapInfoIndex);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.size(10000);
TermQueryBuilder queryBuilder = QueryBuilders.termQuery("name", name);
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("time");
rangeQueryBuilder.gte(startTime);
rangeQueryBuilder.lt(endTime);
BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
boolBuilder.must(queryBuilder);
boolBuilder.must(rangeQueryBuilder);
searchSourceBuilder.query(boolBuilder);
searchRequest.source(searchSourceBuilder);
List<InfoEntity> list = new ArrayList<>();
try {
SearchResponse searchResponse = client.search(searchRequest,
RequestOptions.DEFAULT);
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit searchHit : searchHits) {
InfoEntity infoEntity = new InfoEntity();
Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
Long time = (Long) sourceAsMap.get("time");
String name= (String) sourceAsMap.get("name");
infoEntity.setName(name);
infoEntity.setTime(time);
snapList.add(infoEntity);
}
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
相關文章
- ES操作RestHighLevelClient手冊RESTclient
- RestHighLevelClient查詢esRESTclient
- Java API操作ESJavaAPI
- java客戶端查詢ES操作步驟Java客戶端
- Java8之Stream常用操作方式Java
- java操作Oracle 方式一 ( 連線-》操作-》斷開連線 )JavaOracle
- kibana操作es
- es請求方式呼叫
- es-for-Laravel: Composer 包安裝, Laravel 最簡單的方式操作 ElasticsearchLaravelElasticsearch
- java中四種操作xml方式的比較JavaXML
- ES6操作字串字串
- Java8-9-Stream介紹與操作方式詳解Java
- Python連線es筆記三之es更新操作Python筆記
- ES6非同步方式全面解析非同步
- ES入門三部曲:索引操作,對映操作,文件操作索引
- 用easy-es簡化ElasticSearch操作Elasticsearch
- ElasticSearch 獲取es資訊以及索引操作Elasticsearch索引
- 中介軟體:ElasticSearch元件RestHighLevelClient用法詳解Elasticsearch元件RESTclient
- java io 多種檔案操作方式(位元組、字元、行、隨機)Java字元隨機
- JavaScript原型鏈以及ES3、ES5、ES6實現繼承的不同方式JavaScript原型S3繼承
- 「乾貨」細說 Array 的常用操作(ES5 和 ES6)
- es6迴圈操作方法合集
- COOKIE的幾種操作方式Cookie
- ES6最簡單的方式訪問MongoDBMongoDB
- VUE 未來代理操作:ES6 Proxy代理Vue
- 一個ES設定操作引發的“血案”
- Gitee熱榜第一!讓你可以像操作SQL一樣操作ESGiteeSQL
- java啟動方式Java
- JS的reduce使用及操作方式JS
- Java操作WordJava
- java操作excelJavaExcel
- JAVA操作XMLJavaXML
- Java操作MongoDBJavaMongoDB
- Java 操作PDFJava
- java session操作JavaSession
- ES 筆記四:文件的基本 CRUD 與批量操作筆記
- es6新增陣列方法簡便了哪些操作?陣列
- ES6的這些操作技巧,你會嗎?