
1. 簡述
-
Elasticsearch是基於Lucene開發的一個分布式全文檢索框架,向Elasticsearch中存儲和從Elasticsearch中查詢,格式是json。 -
向
Elasticsearch中存儲數據,其實就是向es中的index下面的type中存儲json類型的數據。 -
elasticsearch提供了很多語言的客戶端用於操作elasticsearch服務,例如:java、python、.net、JavaScript、PHP等。本文主要介紹如何使用java語言來操作elasticsearch服務。在elasticsearch的官網上提供了兩種java語言的API,一種是Java Transport Client,一種是Java REST Client。
Java Transport Client** 是基於 TCP 協議交互的,**在elasticsearch 7.0+版本后官方不再贊成使用,在Elasticsearch 8.0的版本中完全移除TransportClient
**
Java REST Client是基於 HTTP 協議交互,**而Java REST Client又分為Java Low Level REST Client和Java High Level REST Client
Java High Level REST Client是在Java Low Level REST Client的基礎上做了封裝,使其以更加面向對象和操作更加便利的方式調用elasticsearch服務。
官方推薦使用
Java High Level REST Client,因為在實際使用中,Java Transport Client在大並發的情況下會出現連接不穩定的情況。
那接下來我們就來看看elasticsearch提供的Java High Level REST Client(以下簡稱高級REST客戶端)的一些基礎的操作,跟多的操作大家自行閱讀elasticsearch的官方文檔:[https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html)
2. 准備
-
環境:
Windows 10elasticsearch 7.91IDEAMavenJava 8
高級客戶端需要
Java 1.8並依賴於Elasticsearch core項目
- 依賴:
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.9.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.9.1</version>
</dependency>
3. 初始化
- 實例需要構建 REST 低級客戶端生成器,如下所示:
RestHighLevelClient
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http")));
- 高級客戶端將在內部創建用於基於提供的生成器執行請求的低級客戶端。該低級客戶端維護一個連接池並啟動一些線程,因此,當您很好地完成高級客戶端時,您應該關閉該高級客戶端,然后關閉內部低級客戶端以釋放這些資源。這可以通過 以下時間完成:
close
client.close();
在有關 Java 高級客戶端的本文檔的其余部分中,實例將引用為 。
RestHighLevelClientclient
案例:
- 查詢
index代碼:
public static void main(String[] args) {
RestClientBuilder builder = RestClient.builder(
new HttpHost(
"127.0.0.1", //es主機 IP
9200 // es 端口http
)
);
RestHighLevelClient client = new RestHighLevelClient(builder);
GetRequest request = new GetRequest(
"blog1", //索引
"1" //文檔ID
);
//當針對不存在的索引執行獲取請求時,響應404狀態碼,將引發IOException,需要按如下方式處理:
GetResponse documentFields = null;
try {
documentFields = client.get(request, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
////處理因為索引不存在而拋出的異常情況
}
System.out.println(documentFields);
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
- 查詢結果:
{
"_index": "blog1",
"_type": "_doc",
"_id": "1",
"_version": 1,
"_seq_no": 0,
"_primary_term": 1,
"found": true,
"_source": {
"age": 1,
"country": "fuzhou",
"date": "2020-09-10",
"name": "ngitvusercancel"
}
}
上述是一個案例的展示,讓我們初步了解通過
Java的高級restful客戶端來訪問, 下面我們將進行相關Api的介紹
4. 索引 API (Index Api)
4.1 創建索引(Create Index API)
4.1.1 案例:
/*
* 創建索引.
* url:https://i-code.online/
*/
public static void main(String[] args) {
//創建鏈接信息
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200)));
//創建索引請求 索引名稱 student
CreateIndexRequest createIndexRequest = new CreateIndexRequest("student-1");
//創建索引時可以設置與之相關的 特定配置
createIndexRequest.settings(Settings.builder()
.put("index.number_of_shards",3) //分片數
.put("index.number_of_replicas",2) //備份數
);
//創建文檔類型映射
createIndexRequest.mapping("{\n" +
" \"properties\": {\n" +
" \"id\": {\n" +
" \"type\": \"long\",\n" +
" \"store\": true\n" +
" },\n" +
" \"name\": {\n" +
" \"type\": \"text\",\n" +
" \"index\": true,\n" +
" \"analyzer\": \"ik_max_word\"\n" +
" },\n" +
" \"content\": {\n" +
" \"type\": \"text\",\n" +
" \"index\": true,\n" +
" \"analyzer\": \"ik_max_word\"\n" +
" }\n" +
" }\n" +
"}",
XContentType.JSON //類型映射,需要的是一個JSON字符串
);
//可選參數
//超時,等待所有節點被確認(使用TimeValue方式)
createIndexRequest.setTimeout(TimeValue.timeValueMinutes(1));
try {
//同步執行
CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
//返回的CreateIndexResponse允許檢索有關執行的操作的信息,如下所示:
boolean acknowledged = createIndexResponse.isAcknowledged();//指示是否所有節點都已確認請求
boolean shardsAcknowledged = createIndexResponse.isShardsAcknowledged();//指示是否在超時之前為索引中的每個分片啟動了必需的分片副本數
System.out.println("acknowledged:"+acknowledged);
System.out.println("shardsAcknowledged:"+shardsAcknowledged);
System.out.println(createIndexResponse.index());
} catch (IOException e) {
e.printStackTrace();
}
try {
//關閉客戶端鏈接
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
上述是一個 index 創建的過程,具體的細節操作
api下面詳解
4.1.2 創建索引請求
- 需要參數:
CreateIndexRequestindex
CreateIndexRequest request = new CreateIndexRequest("twitter");//<1>
<1>要創建索引
4.1.3 索引設置
- 創建的每個索引都可以具有與其關聯的特定設置。
//此索引的設置
request.settings(Settings.builder()
.put("index.number_of_shards", 3) //分片數
.put("index.number_of_replicas", 2)//備份數
);
4.1.4 索引映射
- 可以創建索引,並創建其文檔類型的映射
request.mapping(
"{\n" +
" "properties": {\n" +
" "message": {\n" +
" "type": "text"\n" +
" }\n" +
" }\n" +
"}", //<1> 要定義的類型
XContentType.JSON); //<2> 此類型的映射,作為 JSON 字符串提供
<1>要定義的類型
<2>此類型的映射,作為JSON字符串提供
- 除了上面顯示的示例之外,還可以以不同的方式提供映射源:
String
Map<String, Object> message = new HashMap<>();
message.put("type", "text");
Map<String, Object> properties = new HashMap<>();
properties.put("message", message);
Map<String, Object> mapping = new HashMap<>();
mapping.put("properties", properties);
request.mapping(mapping); //接受map的映射集合,自動轉為 json
提供自動轉換為
JSON格式的映射源Map
這種方式多層嵌套,在使用過程中注意嵌套,上面標簽嵌套:properties -> message -> type
XContentBuilder builder = XContentFactory.jsonBuilder(); // 使用XContentBuilder內容生成器
builder.startObject();
{
builder.startObject("properties");
{
builder.startObject("message");
{
builder.field("type", "text");
}
builder.endObject();
}
builder.endObject();
}
builder.endObject();
4.1.5 索引別名
- 可以在索引創建時設置別名
request.alias(new Alias("twitter_alias").filter(QueryBuilders.termQuery("user", "kimchy"))); //要定義的別名
4.1.6 提供整個源
- 前面我們都是一步一步的設置的,其實也可以提供整個源,包括其所有部分(映射、設置和別名):
request.source("{\n" +
" \"settings\" : {\n" +
" \"number_of_shards\" : 1,\n" +
" \"number_of_replicas\" : 0\n" +
" },\n" +
" \"mappings\" : {\n" +
" \"properties\" : {\n" +
" \"message\" : { \"type\" : \"text\" }\n" +
" }\n" +
" },\n" +
" \"aliases\" : {\n" +
" \"twitter_alias\" : {}\n" +
" }\n" +
"}", XContentType.JSON);
作為 JSON 字符串提供的源。它也可以作為 或 提供。MapXContentBuilder
4.1.7 可選參數
- 可以選擇提供以下參數:
request.setTimeout(TimeValue.timeValueMinutes(2));
超時以等待所有節點將索引創建確認為
TimeValue
request.setMasterTimeout(TimeValue.timeValueMinutes(1));
以作為
TimeValue
request.waitForActiveShards(ActiveShardCount.from(2));
request.waitForActiveShards(ActiveShardCount.DEFAULT);
在創建索引
API返回響應之前等待的活動分片副本數,作為int
在創建索引API返回響應之前等待的活動分片副本數,作為ActiveShardCount
4.1.8 同步執行
- 以下列方式執行 時,客戶端將等待 返回 ,然后再繼續執行代碼:
CreateIndexRequest CreateIndexResponse
CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
同步調用可能會引發 在高級 REST 客戶端中無法解析 REST 響應、請求會發出時間或類似情況下沒有從服務器返回的響應的情況下。
IOException
在服務器返回 或 錯誤代碼的情況下,高級客戶端嘗試分析響應正文錯誤詳細信息,然后引發泛型,並將原始代碼添加為抑制異常。4xx 5xx ElasticsearchExceptionResponseException
4.1.9 異步執行
- 也可以以異步方式執行 ,以便客戶端可以直接返回。用戶需要指定如何通過將請求和偵聽器傳遞到異步創建索引方法來處理響應或潛在故障:
CreateIndexRequest
client.indices().createAsync(request, RequestOptions.DEFAULT, listener);
執行完成時要執行和要使用的
CreateIndexRequest ActionListener
- 異步方法不會阻止並立即返回。完成后,如果執行成功完成,則使用
onResponse方法調用 ,如果執行失敗,則使用onFailure該方法。失敗方案和預期異常與同步執行案例相同。ActionListener
典型的偵聽器如下所示:
ActionListener<CreateIndexResponse> listener =
new ActionListener<CreateIndexResponse>() {
@Override
public void onResponse(CreateIndexResponse createIndexResponse) {
//成功執行時調用。
}
@Override
public void onFailure(Exception e) {
//當整個失敗時調用
}
};
4.1.10 創建索引響應
- 返回的允許檢索有關執行操作的信息,如下所示:
CreateIndexResponse
boolean acknowledged = createIndexResponse.isAcknowledged(); // <1>
boolean shardsAcknowledged = createIndexResponse.isShardsAcknowledged(); // <2>
<1> 指示所有節點是否都已確認請求
<2> 指示在計時之前是否為索引中的每個分片啟動所需的分片副本數
4.2 刪除索引(Delete Index Api)
4.2.1 案例:
/**
* 刪除索引.
* url:https://i-code.online/
* @param args
*/
public static void main(String[] args) {
//1. 創建客戶端
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200)));
//2. 創建DeleteIndexRequest 接受 index(索引名) 參數
DeleteIndexRequest request = new DeleteIndexRequest("student");
//超時以等待所有節點確認索引刪除 參數為 TimeValue 類型
request.timeout(TimeValue.timeValueMinutes(1));
//連接master節點的超時時間(使用TimeValue方式)
request.masterNodeTimeout(TimeValue.timeValueMinutes(1));
try {
// 調用delete
AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.printf("isAcknowledged:%s", response.isAcknowledged());
} catch (IOException e) {
e.printStackTrace();
}
}
4.2.2 刪除索引請求
- 需要參數:
DeleteIndexRequestindex
DeleteIndexRequest request = new DeleteIndexRequest("posts");//<1> <1> 索引(index)名
<1> 索引(index)名
4.2.3 可選參數
- 可以選擇提供以下參數:
request.timeout(TimeValue.timeValueMinutes(2));
request.timeout("2m");
超時以等待所有節點確認索引刪除為
TimeValue類型
超時以等待所有節點確認索引刪除為
String類型
request.masterNodeTimeout(TimeValue.timeValueMinutes(1));//連接master節點的超時時間(使用TimeValue方式)
request.masterNodeTimeout("1m");//連接master節點的超時時間(使用字符串方式)
連接master節點的超時時間(使用TimeValue方式)
連接master節點的超時時間(使用字符串方式)
request.indicesOptions(IndicesOptions.lenientExpandOpen());
設置控制如何解析不可用的索引以及如何展開通配符表達式IndicesOptions
4.2.4 同步執行
- 以下列方式執行
DeleteIndexRequest時,客戶端將等待DeleteIndexResponse返回 ,然后再繼續執行代碼:DeleteIndexRequestDeleteIndexResponse
AcknowledgedResponse deleteIndexResponse = client.indices().delete(request, RequestOptions.DEFAULT);
同步調用可能會引發 在高級
REST客戶端中無法解析REST響應、請求會發出時間或類似情況下沒有從服務器返回的響應的情況下。IOException
在服務器返回 或 錯誤代碼的情況下,高級客戶端嘗試分析響應正文錯誤詳細信息,然后引發泛型,並將原始代碼添加為抑制異常。4xx 5xx ElasticsearchExceptionResponseException
4.2.5 異步執行
- 也可以以異步方式執行 ,以便客戶端可以直接返回。用戶需要指定如何通過將請求和偵聽器傳遞到異步刪除索引方法來處理響應或潛在故障:
DeleteIndexRequest
client.indices().deleteAsync(request, RequestOptions.DEFAULT, listener); //<1>
<1> 執行完成時要執行和要使用的DeleteIndexRequest ActionListener
異步方法不會阻止並立即返回。完成后,如果執行成功完成,則使用 ActionListener#onResponse 方法調用 ,如果執行失敗,則使用 ActionListener# onFailure 該方法。失敗方案和預期異常與同步執行案例相同。
典型的偵聽器如下所示:delete-index
ActionListener<AcknowledgedResponse> listener =
new ActionListener<AcknowledgedResponse>() {
@Override
public void onResponse(AcknowledgedResponse deleteIndexResponse) {
//成功執行時調用。
}
@Override
public void onFailure(Exception e) {
//當整個失敗時調用。DeleteIndexRequest
}
};
4.2.6 刪除索引響應
- 返回的允許檢索有關執行操作的信息,如下所示:
DeleteIndexResponse
boolean acknowledged = deleteIndexResponse.isAcknowledged(); //<1> 指示所有節點是否都已確認請求
<1> 指示所有節點是否都已確認請求
- 如果未找到索引,將引發 :
ElasticsearchException
try {
DeleteIndexRequest request = new DeleteIndexRequest("does_not_exist");
client.indices().delete(request, RequestOptions.DEFAULT);
} catch (ElasticsearchException exception) {
if (exception.status() == RestStatus.NOT_FOUND) {
//如果未找到要刪除的索引,則進行""
}
}
如果未找到要刪除的索引,則進行""
4.3 索引存在(Index Exists Api)
4.3.1 案例:
/**
* 索引是否存在Api
* url:www.i-code.online
* @param args
*/
public static void main(String[] args) {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200)));
//創建請求
GetIndexRequest request = new GetIndexRequest("student");
//<1> 是返回本地信息還是從主節點檢索狀態
request.local(false);
//<2> 返回結果為適合人類的格式
request.humanReadable(true);
try {
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
} catch (IOException e) {
e.printStackTrace();
}
}
4.3.2 索引存在請求
- 高級 REST 客戶端使用 "Index Exists API"。索引名稱是必需的。
GetIndexRequest
GetIndexRequest request = new GetIndexRequest("twitter"); //<1> index 名稱
<1> index 名稱
4.3.3 可選參數
- 索引存在 API 還接受以下可選參數,通過 :
GetIndexRequest
request.local(false);//<1> 是返回本地信息還是從主節點檢索狀態
request.humanReadable(true); //<2> 返回結果為適合人類的格式
request.includeDefaults(false); //<3> 是否返回每個索引的所有默認設置
request.indicesOptions(indicesOptions); //<4> 控制如何解析不可用的索引以及如何展開通配符表達式
<1> 是返回本地信息還是從主節點檢索狀態
<2> 返回結果為適合人類的格式
<3> 是否返回每個索引的所有默認設置
<4> 控制如何解析不可用的索引以及如何展開通配符表達式
4.3.4 同步執行
- 以下列方式執行 時,客戶端將等待 返回 ,然后再繼續執行代碼:
GetIndexRequestboolean
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
與其他同步的相同
4.3.5 異步執行
- 也可以以異步方式執行 ,以便客戶端可以直接返回。用戶需要指定如何通過將請求和偵聽器傳遞到異步索引存在的方法來處理響應或潛在故障:
GetIndexRequest
client.indices().existsAsync(request, RequestOptions.DEFAULT, listener);//<1>執行完成時要執行和要使用的 GetIndexRequest ActionListener
<1>執行完成時要執行和要使用的
GetIndexRequestActionListener
異步的處理邏輯與其他異步的相同,都是實現ActionListener的方法
4.3.6 響應
5. 文檔 Api (Document APIs)
5.1 索引 API (Index Api)
5.1.1 案例:
- 添加記錄
private static void test02() {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200)));
//創建請求, 參數index名稱
IndexRequest request = new IndexRequest("student");
//請求的模式,CREATE: 創建模式,如果已經存在則報錯 Index:存在則不再創建,也不報錯
request.opType(DocWriteRequest.OpType.INDEX);
String json = "{\n" +
" \"id\": 12,\n" +
" \"name\": \"admin\",\n" +
" \"content\": \"步的處理邏輯與其他異步的相同,都是實現ActionListener 的方法\"\n" +
"}";
request.id("1").source(
json,
XContentType.JSON
);
IndexResponse indexResponse = null;
try {
//調用 index 方法
indexResponse = client.index(request, RequestOptions.DEFAULT);
System.out.println(indexResponse.getVersion());
System.out.println(indexResponse.getIndex());
System.out.println(indexResponse.getId());
System.out.println(indexResponse.status());
} catch (ElasticsearchStatusException | IOException e) {
e.printStackTrace();
}
}
5.1.2 索引請求
- 需要以下參數:
IndexRequest
//創建請求, 參數index名稱
IndexRequest request = new IndexRequest("student"); //<1> index 名稱
String json = "{\n" +
" \"id\": 12,\n" +
" \"name\": \"admin\",\n" +
" \"content\": \"步的處理邏輯與其他異步的相同,都是實現ActionListener 的方法\"\n" +
"}";
request
.id("1") // <2> 指定文檔 ID
.source(
json,
XContentType.JSON // <3> 指定參數類型,json
);
<1> index 名稱指數
<2> 請求的文檔 ID
<3> 指定參數類型,json
提供文檔源
- 除了上面顯示的示例之外,還可以以不同的方式提供文檔源:
String
Map<String, Object> jsonMap = new HashMap<>();
jsonMap.put("id", 1);
jsonMap.put("name", "Admin);
jsonMap.put("content", "步的處理邏輯與其他異步的相同");
IndexRequest indexRequest = new IndexRequest("student").id("1").source(jsonMap);
文檔源作為 自動轉換為
JSON格式的Map
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
{
builder.field("id", 1);
builder.field("name", "admin);
builder.field("content", "trying out Elasticsearch");
}
builder.endObject();
IndexRequest indexRequest = new IndexRequest("student").id("1").source(builder);
文檔源作為對象提供,彈性搜索內置幫助器生成
JSON內容XContentBuilder
IndexRequest indexRequest = new IndexRequest("student")
.id("1")
.source("id", 1,
"name", "admin",
"content", "trying out Elasticsearch");
作為密鑰對提供的文檔源,該源將轉換為 JSON 格式Object
5.1.3 可選參數
- 可以選擇提供以下參數:
request.routing("routing"); //<1>
<1> 路由值
request.timeout(TimeValue.timeValueSeconds(1)); //<1>
request.timeout("1s"); // <2>
<1> 超時以等待主分片 作為 TimeValue
<2> 超時以等待主分片 作為 String
request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL); //<1>
request.setRefreshPolicy("wait_for"); //<2>
<1> 將策略刷新 為實例
WriteRequest.RefreshPolicy
<2> 將策略刷新 為String
request.version(2);
版本
request.versionType(VersionType.EXTERNAL); //版本類型
版本類型
request.opType(DocWriteRequest.OpType.CREATE);//<1>
request.opType("create");//<2>
<1> 作為值提供的操作類型
DocWriteRequest.OpType
<2> 提供的操作類型可以是 或(默認)Stringcreateindex
request.setPipeline("pipeline");
在索引文檔之前要執行的包含管道的名稱
5.1.4 同步執行
- 以下列方式執行 時,客戶端將等待 返回 ,然后再繼續執行代碼:
IndexRequestIndexResponse
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
- 同步調用可能會引發 在高級 REST 客戶端中無法解析 REST 響應、請求會發出時間或類似情況下沒有從服務器返回的響應的情況下。
IOException - 在服務器返回 或 錯誤代碼的情況下,高級客戶端嘗試分析響應正文錯誤詳細信息,然后引發泛型,並將原始代碼添加為抑制異常。
4xx 5xx ElasticsearchExceptionResponseException
5.1.5 異步執行
- 也可以以異步方式執行 ,以便客戶端可以直接返回。用戶需要指定如何通過將請求和偵聽器傳遞到異步索引方法來處理響應或潛在故障:
IndexRequest
client.indexAsync(request, RequestOptions.DEFAULT, listener); //<1>
<1> 執行完成時要執行和要使用的
IndexRequestActionListener
- 異步方法不會阻止並立即返回。完成后,如果執行成功完成,則使用 方法調用 ,如果執行失敗,則使用 該方法。失敗方案和預期異常與同步執行案例相同。
ActionListeneronResponseonFailure - 典型的偵聽器如下所示:index
listener = new ActionListener<IndexResponse>() {
@Override
public void onResponse(IndexResponse indexResponse) {
//<1> 成功執行時調用。
}
@Override
public void onFailure(Exception e) {
//<2> 當整個失敗時調用。IndexRequest
}
};
<1> 成功執行時調用。
5.1.6 索引響應
- 返回的允許檢索有關執行操作的信息,如下所示:
IndexResponse
String index = indexResponse.getIndex();
String id = indexResponse.getId();
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
//<1>
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
//<2>
}
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
// <3>
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure :
shardInfo.getFailures()) {
String reason = failure.reason(); //<4>
}
}
<1> 處理(如果需要)首次創建文檔的情況
<2> 處理(如果需要)文檔被重寫的情況,因為它已經存在
<3> 處理成功分片數少於總分片的情況
<4> 處理潛在的故障
- 如果存在版本沖突,將引發 :
ElasticsearchException
IndexRequest request = new IndexRequest("posts")
.id("1")
.source("field", "value")
.setIfSeqNo(10L)
.setIfPrimaryTerm(20);
try {
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
} catch(ElasticsearchException e) {
if (e.status() == RestStatus.CONFLICT) {
//<1>
}
}
<1> 引發異常指示返回版本沖突錯誤
- 在設置為且已存在具有相同索引和 ID 的文檔的情況下,將發生相同的情況:
opTypecreate
IndexRequest request = new IndexRequest("posts")
.id("1")
.source("field", "value")
.opType(DocWriteRequest.OpType.CREATE);
try {
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
} catch(ElasticsearchException e) {
if (e.status() == RestStatus.CONFLICT) {
//<1>
}
}
<1>引發異常指示返回版本沖突錯誤
5.2 獲取Api (Get API)
5.2.1 案例:
private static void test01(){
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200)));
GetRequest request = new GetRequest("student");
// 為特定字段 配置 源包含
String[] includs = {"name","id","content"};
String[] excluds = {"id"};
FetchSourceContext context = new FetchSourceContext(true,includs,excluds);
request.id("1").version(2).fetchSourceContext(context);
try {
GetResponse documentFields = client.get(request, RequestOptions.DEFAULT);
if (documentFields.isExists()) {
//檢索名稱
System.out.println(documentFields.getIndex());
// 獲取文檔源的 Map 結果
System.out.println(documentFields.getSource());
// 獲取源作為 Map
System.out.println(documentFields.getSourceAsMap());
// 獲取源作為 bytes
System.out.println(documentFields.getSourceAsBytes());
}else {
System.out.println("不錯在該數據");
}
} catch (IOException e) {
e.printStackTrace();
}
}
5.2.2 獲取請求
- 需要以下參數:GetRequest
GetRequest getRequest = new GetRequest(
"posts", //<1>
"1"); //<1>
<1> 索引名稱
<2> 文檔 ID
5.2.3 可選參數
- 可以選擇提供以下參數:
request.fetchSourceContext(FetchSourceContext.DO_NOT_FETCH_SOURCE);
禁用源檢索,默認情況下啟用
String[] includes = new String[]{"message", "*Date"};
String[] excludes = Strings.EMPTY_ARRAY;
FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes);
request.fetchSourceContext(fetchSourceContext);
為特定字段 配置 源包含
includes: 檢索結果所包含的字段
excludes: 檢索結果排除的字段
String[] includes = Strings.EMPTY_ARRAY;
String[] excludes = new String[]{"message"};
FetchSourceContext fetchSourceContext =
new FetchSourceContext(true, includes, excludes);
request.fetchSourceContext(fetchSourceContext);
為特定字段配置源排除
request.storedFields("message");
GetResponse getResponse = client.get(request, RequestOptions.DEFAULT);
String message = getResponse.getField("message").getValue();
為特定存儲字段配置檢索(要求字段單獨存儲在映射中)
檢索存儲的字段(要求該字段單獨存儲在映射中)message
request.routing("routing");
路由值
request.preference("preference");
首選項值
request.realtime(false);
將實時標志設置為(默認情況下)falsetrue
request.refresh(true);
在檢索文檔之前執行刷新(默認情況下)false
request.version(2);
版本
request.versionType(VersionType.EXTERNAL);
版本類型
5.2.4 同步執行
- 以下列方式執行 時,客戶端將等待 返回 ,然后再繼續執行代碼:
GetRequestGetResponse
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
-
同步調用可能會引發 在高級 REST 客戶端中無法解析 REST 響應、請求會發出時間或類似情況下沒有從服務器返回的響應的情況下。IOException
-
在服務器返回 或 錯誤代碼的情況下,高級客戶端嘗試分析響應正文錯誤詳細信息,然后引發泛型,並將原始代碼添加為抑制異常。4xx5xxElasticsearchExceptionResponseException
5.2.5 異步執行
- 也可以以異步方式執行 ,以便客戶端可以直接返回。用戶需要指定如何通過將請求和偵聽器傳遞到異步獲取方法來處理響應或潛在故障:
GetRequest
client.getAsync(request, RequestOptions.DEFAULT, listener);
執行完成時要執行和要使用的
GetRequestActionListener
-
異步方法不會阻止並立即返回。完成后,如果執行成功完成,則使用 方法調用 ,如果執行失敗,則使用 該方法。失敗方案和預期異常與同步執行案例相同。ActionListeneronResponseonFailure
-
典型的偵聽器如下所示:
get
ActionListener<GetResponse> listener = new ActionListener<GetResponse>() {
@Override
public void onResponse(GetResponse getResponse) {
//成功執行時調用
}
@Override
public void onFailure(Exception e) {
//當整個失敗時調用。GetRequest
}
};
5.2.6 獲取響應
- 返回的允許檢索請求的文檔及其元數據和最終存儲的字段。
GetResponse
String index = getResponse.getIndex();
String id = getResponse.getId();
if (getResponse.isExists()) {
long version = getResponse.getVersion();
String sourceAsString = getResponse.getSourceAsString(); // <1>
Map<String, Object> sourceAsMap = getResponse.getSourceAsMap(); // <2>
byte[] sourceAsBytes = getResponse.getSourceAsBytes(); // <3>
} else {
// <4>
}
<1> 將文檔檢索為
String
<2> 將文檔檢索為Map<String, Object>
<3> 將文檔檢索為byte[]
<4> 處理找不到文檔的方案。請注意,盡管返回的響應具有狀態代碼,但返回的是有效的,而不是引發異常。此類響應不保存任何源文檔,其方法將返回。404 GetResponseisExistsfalse
- 當對不存在的索引執行 get 請求時,響應具有狀態代碼,即需要按如下方式處理的已引發請求:
404 ElasticsearchException
GetRequest request = new GetRequest("does_not_exist", "1");
try {
GetResponse getResponse = client.get(request, RequestOptions.DEFAULT);
} catch (ElasticsearchException e) {
if (e.status() == RestStatus.NOT_FOUND) {
//<1> 處理引發異常,因為索引不存在
}
}
<1> 處理引發異常,因為索引不存在
- 如果請求了特定的文檔版本,並且現有文檔具有不同的版本號,則引發版本沖突:
try {
GetRequest request = new GetRequest("posts", "1").version(2);
GetResponse getResponse = client.get(request, RequestOptions.DEFAULT);
} catch (ElasticsearchException exception) {
if (exception.status() == RestStatus.CONFLICT) {
// <1>
}
}
<1> 引發異常指示返回版本沖突錯誤
6. 結語
其實很多 Api 的使用都是類似相同的,這里我們不再對其他 Api 進行解析,需要了解的完全可以去光網文檔查看,文檔地址在問上漲上面有。
本文由AnonyStar 發布,可轉載但需聲明原文出處。
仰慕「優雅編碼的藝術」 堅信熟能生巧,努力改變人生
歡迎關注微信公賬號 :雲棲簡碼 獲取更多優質文章
更多文章關注筆者博客 :雲棲簡碼
