1. 簡(jiǎn)述
-
Elasticsearch
是基于Lucene
開(kāi)發(fā)的一個(gè)分布式全文檢索框架,向Elasticsearch
中存儲(chǔ)和從Elasticsearch
中查詢,格式是json。 -
向
Elasticsearch
中存儲(chǔ)數(shù)據(jù),其實(shí)就是向es
中的index
下面的type
中存儲(chǔ)json
類型的數(shù)據(jù)。 -
elasticsearch
提供了很多語(yǔ)言的客戶端用于操作elasticsearch
服務(wù),例如:JAVA
、Python
、.net
、JavaScript
、php
等。本文主要介紹如何使用java
語(yǔ)言來(lái)操作elasticsearch
服務(wù)。在elasticsearch
的官網(wǎng)上提供了兩種java
語(yǔ)言的API
,一種是Java Transport Client
,一種是Java REST Client
。
Java Transport Client
** 是基于 TCP 協(xié)議交互的,**在elasticsearch 7.0+
版本后官方不再贊成使用,在Elasticsearch 8.0的版本中完全移除TransportClient
**
Java REST Client
是基于 HTTP 協(xié)議交互,**而Java REST Client
又分為Java Low Level REST Client
和Java High Level REST Client
Java High Level REST Client
是在Java Low Level REST Client
的基礎(chǔ)上做了封裝,使其以更加面向?qū)ο蠛筒僮鞲颖憷姆绞秸{(diào)用elasticsearch
服務(wù)。
官方推薦使用
Java High Level REST Client
,因?yàn)樵趯?shí)際使用中,Java Transport Client
在大并發(fā)的情況下會(huì)出現(xiàn)連接不穩(wěn)定的情況。那接下來(lái)我們就來(lái)看看elasticsearch
提供的Java High Level REST Client
(以下簡(jiǎn)稱高級(jí)REST客戶端)的一些基礎(chǔ)的操作,跟多的操作大家自行閱讀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. 準(zhǔn)備
-
環(huán)境:
windows 10
elasticsearch 7.91
IDEA
Maven
Java 8
高級(jí)客戶端需要
Java 1.8
并依賴于Elasticsearch core
項(xiàng)目
-
依賴:
<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. 初始化
- 實(shí)例需要構(gòu)建 REST 低級(jí)客戶端生成器,如下所示:
RestHighLevelClient
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder( new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http")));
- 高級(jí)客戶端將在內(nèi)部創(chuàng)建用于基于提供的生成器執(zhí)行請(qǐng)求的低級(jí)客戶端。該低級(jí)客戶端維護(hù)一個(gè)連接池并啟動(dòng)一些線程,因此,當(dāng)您很好地完成高級(jí)客戶端時(shí),您應(yīng)該關(guān)閉該高級(jí)客戶端,然后關(guān)閉內(nèi)部低級(jí)客戶端以釋放這些資源。這可以通過(guò) 以下時(shí)間完成:
close
client.close();
在有關(guān) Java 高級(jí)客戶端的本文檔的其余部分中,實(shí)例將引用為 。
RestHighLevelClient
client
案例:
- 查詢
index
代碼:
public static void main(String[] args) {
RestClientBuilder builder = RestClient.builder( new HttpHost(
"127.0.0.1", //es主機(jī) IP
9200 // es 端口http
) ); RestHighLevelClient client = new RestHighLevelClient(builder);
GetRequest request = new GetRequest(
"blog1", //索引
"1" //文檔ID
); //當(dāng)針對(duì)不存在的索引執(zhí)行獲取請(qǐng)求時(shí),響應(yīng)404狀態(tài)碼,將引發(fā)IOException,需要按如下方式處理:
GetResponse documentFields = null;
try {
documentFields = client.get(request, RequestOptions.DEFAULT); } catch (IOException e) {
e.printStackTrace(); ////處理因?yàn)樗饕淮嬖诙鴴伋龅漠惓G闆r
}
System.out.println(documentFields);
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
- 查詢結(jié)果:
{
"_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"
}}
上述是一個(gè)案例的展示,讓我們初步了解通過(guò)
Java
的高級(jí)restful
客戶端來(lái)訪問(wèn), 下面我們將進(jìn)行相關(guān)Api
的介紹
4. 索引 API (Index Api)
4.1 創(chuàng)建索引(Create Index API)
**
4.1.1 案例:
/*
* 創(chuàng)建索引. * url:https://i-code.online/ */ public static void main(String[] args) { //創(chuàng)建鏈接信息 RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200)));
//創(chuàng)建索引請(qǐng)求 索引名稱 student CreateIndexRequest createIndexRequest = new CreateIndexRequest("student-1");
//創(chuàng)建索引時(shí)可以設(shè)置與之相關(guān)的 特定配置 createIndexRequest.settings(Settings.builder() .put("index.number_of_shards",3) //分片數(shù)
.put("index.number_of_replicas",2) //備份數(shù)
); //創(chuàng)建文檔類型映射 createIndexRequest.mApping("{n" +
" "properties": {n" +
" "id": {n" +
" "type": "long",n" +
" "store": truen" +
" },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 //類型映射,需要的是一個(gè)JSON字符串 ); //可選參數(shù) //超時(shí),等待所有節(jié)點(diǎn)被確認(rèn)(使用TimeValue方式) createIndexRequest.setTimeout(TimeValue.timeValueMinutes(1));
try { //同步執(zhí)行 CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
//返回的CreateIndexResponse允許檢索有關(guān)執(zhí)行的操作的信息,如下所示: boolean acknowledged = createIndexResponse.isAcknowledged();//指示是否所有節(jié)點(diǎn)都已確認(rèn)請(qǐng)求 boolean shardsAcknowledged = createIndexResponse.isShardsAcknowledged();//指示是否在超時(shí)之前為索引中的每個(gè)分片啟動(dòng)了必需的分片副本數(shù) System.out.println("acknowledged:"+acknowledged);
System.out.println("shardsAcknowledged:"+shardsAcknowledged);
System.out.println(createIndexResponse.index()); } catch (IOException e) { e.printStackTrace(); } try { //關(guān)閉客戶端鏈接 client.close();
} catch (IOException e) { e.printStackTrace(); } }
上述是一個(gè) index 創(chuàng)建的過(guò)程,具體的細(xì)節(jié)操作
api
下面詳解
4.1.2 創(chuàng)建索引請(qǐng)求
- 需要參數(shù):
CreateIndexRequestindex
CreateIndexRequest request = new CreateIndexRequest("twitter");//<1>
<1>要?jiǎng)?chuàng)建索引
4.1.3 索引設(shè)置
- 創(chuàng)建的每個(gè)索引都可以具有與其關(guān)聯(lián)的特定設(shè)置。
//此索引的設(shè)置
request.settings(Settings.builder().put("index.number_of_shards", 3) //分片數(shù)
.put("index.number_of_replicas", 2)//備份數(shù)
);
4.1.4 索引映射
- 可以創(chuàng)建索引,并創(chuàng)建其文檔類型的映射
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的映射集合,自動(dòng)轉(zhuǎn)為 json
提供自動(dòng)轉(zhuǎn)換為
JSON
格式的映射源Map
這種方式多層嵌套,在使用過(guò)程中注意嵌套,上面標(biāo)簽嵌套:properties -> message -> type
XContentBuilder builder = XContentFactory.jsonBuilder(); // 使用XContentBuilder內(nèi)容生成器
builder.startObject();{ builder.startObject("properties");
{ builder.startObject("message");
{ builder.field("type", "text");
} builder.endObject(); } builder.endObject();}builder.endObject();
映射作為對(duì)象提供的源,彈性搜索內(nèi)置幫助器,用于生成
JSON
內(nèi)容XContentBuilder
4.1.5 索引別名
- 可以在索引創(chuàng)建時(shí)設(shè)置別名
request.alias(new Alias("twitter_alias").filter(QueryBuilders.termQuery("user", "kimchy"))); //要定義的別名
4.1.6 提供整個(gè)源
- 前面我們都是一步一步的設(shè)置的,其實(shí)也可以提供整個(gè)源,包括其所有部分(映射、設(shè)置和別名):
request.source("{n" +
" "settings" : {n" +
" "number_of_shards" : 1,n" +
" "number_of_replicas" : 0n" +
" },n" +
" "mappings" : {n" +
" "properties" : {n" +
" "message" : { "type" : "text" }n" +
" }n" +
" },n" +
" "aliases" : {n" +
" "twitter_alias" : {}n" +
" }n" +
"}", XContentType.JSON);
作為 JSON 字符串提供的源。它也可以作為 或 提供。MapXContentBuilder
4.1.7 可選參數(shù)
- 可以選擇提供以下參數(shù):
request.setTimeout(TimeValue.timeValueMinutes(2));
超時(shí)以等待所有節(jié)點(diǎn)將索引創(chuàng)建確認(rèn)為
TimeValue
request.setMasterTimeout(TimeValue.timeValueMinutes(1));
以作為
TimeValue
request.waitForActiveShards(ActiveShardCount.from(2));
request.waitForActiveShards(ActiveShardCount.DEFAULT);
在創(chuàng)建索引
API
返回響應(yīng)之前等待的活動(dòng)分片副本數(shù),作為in
t在創(chuàng)建索引API
返回響應(yīng)之前等待的活動(dòng)分片副本數(shù),作為ActiveShardCount
4.1.8 同步執(zhí)行
- 以下列方式執(zhí)行 時(shí),客戶端將等待 返回 ,然后再繼續(xù)執(zhí)行代碼:
CreateIndexRequest CreateIndexResponse
CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
同步調(diào)用可能會(huì)引發(fā) 在高級(jí) REST 客戶端中無(wú)法解析 REST 響應(yīng)、請(qǐng)求會(huì)發(fā)出時(shí)間或類似情況下沒(méi)有從服務(wù)器返回的響應(yīng)的情況下。
IOException
在服務(wù)器返回 或 錯(cuò)誤代碼的情況下,高級(jí)客戶端嘗試分析響應(yīng)正文錯(cuò)誤詳細(xì)信息,然后引發(fā)泛型,并將原始代碼添加為抑制異常。4xx 5xx ElasticsearchExceptionResponseException
4.1.9 異步執(zhí)行
- 也可以以異步方式執(zhí)行 ,以便客戶端可以直接返回。用戶需要指定如何通過(guò)將請(qǐng)求和偵聽(tīng)器傳遞到異步創(chuàng)建索引方法來(lái)處理響應(yīng)或潛在故障:
CreateIndexRequest
client.indices().createAsync(request, RequestOptions.DEFAULT, listener);
執(zhí)行完成時(shí)要執(zhí)行和要使用的
CreateIndexRequest ActionListener
- 異步方法不會(huì)阻止并立即返回。完成后,如果執(zhí)行成功完成,則使用
onResponse
方法調(diào)用 ,如果執(zhí)行失敗,則使用onFailure
該方法。失敗方案和預(yù)期異常與同步執(zhí)行案例相同。ActionListener
典型的偵聽(tīng)器如下所示:
ActionListener<CreateIndexResponse> listener =
new ActionListener<CreateIndexResponse>() {
@Override
public void onResponse(CreateIndexResponse createIndexResponse) {
//成功執(zhí)行時(shí)調(diào)用。
}
@Override
public void onFailure(Exception e) {
//當(dāng)整個(gè)失敗時(shí)調(diào)用
}
};
4.1.10 創(chuàng)建索引響應(yīng)
- 返回的允許檢索有關(guān)執(zhí)行操作的信息,如下所示:
CreateIndexResponse
boolean acknowledged = createIndexResponse.isAcknowledged(); // <1>
boolean shardsAcknowledged = createIndexResponse.isShardsAcknowledged(); // <2>
<1> 指示所有節(jié)點(diǎn)是否都已確認(rèn)請(qǐng)求
<2> 指示在計(jì)時(shí)之前是否為索引中的每個(gè)分片啟動(dòng)所需的分片副本數(shù)
4.2 刪除索引(Delete Index Api)
4.2.1 案例:
/**
* 刪除索引. * url:https://i-code.online/
* @param args */
public static void main(String[] args) {
//1. 創(chuàng)建客戶端
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200)));
//2. 創(chuàng)建DeleteIndexRequest 接受 index(索引名) 參數(shù)
DeleteIndexRequest request = new DeleteIndexRequest("student");
//超時(shí)以等待所有節(jié)點(diǎn)確認(rèn)索引刪除 參數(shù)為 TimeValue 類型
request.timeout(TimeValue.timeValueMinutes(1));
//連接master節(jié)點(diǎn)的超時(shí)時(shí)間(使用TimeValue方式)
request.masterNodeTimeout(TimeValue.timeValueMinutes(1));
try {
// 調(diào)用delete
AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.printf("isAcknowledged:%s", response.isAcknowledged());
} catch (IOException e) {
e.printStackTrace();
}
}
4.2.2 刪除索引請(qǐng)求
- 需要參數(shù):
DeleteIndexRequestindex
DeleteIndexRequest request = new DeleteIndexRequest("posts");//<1> <1> 索引(index)名
<1> 索引(index)名
4.2.3 可選參數(shù)
- 可以選擇提供以下參數(shù):
request.timeout(TimeValue.timeValueMinutes(2));
request.timeout("2m");
超時(shí)以等待所有節(jié)點(diǎn)確認(rèn)索引刪除為
TimeValue
類型
超時(shí)以等待所有節(jié)點(diǎn)確認(rèn)索引刪除為
String
類型
request.masterNodeTimeout(TimeValue.timeValueMinutes(1));//連接master節(jié)點(diǎn)的超時(shí)時(shí)間(使用TimeValue方式)
request.masterNodeTimeout("1m");//連接master節(jié)點(diǎn)的超時(shí)時(shí)間(使用字符串方式)
連接master節(jié)點(diǎn)的超時(shí)時(shí)間(使用TimeValue方式)連接master節(jié)點(diǎn)的超時(shí)時(shí)間(使用字符串方式)
request.indicesOptions(IndicesOptions.lenientExpandOpen());
設(shè)置控制如何解析不可用的索引以及如何展開(kāi)通配符表達(dá)式IndicesOptions
4.2.4 同步執(zhí)行
- 以下列方式執(zhí)行
DeleteIndexRequest
時(shí),客戶端將等待DeleteIndexResponse
返回 ,然后再繼續(xù)執(zhí)行代碼:DeleteIndexRequest
DeleteIndexResponse
AcknowledgedResponse deleteIndexResponse = client.indices().delete(request, RequestOptions.DEFAULT);
同步調(diào)用可能會(huì)引發(fā) 在高級(jí)
REST
客戶端中無(wú)法解析REST
響應(yīng)、請(qǐng)求會(huì)發(fā)出時(shí)間或類似情況下沒(méi)有從服務(wù)器返回的響應(yīng)的情況下。IOException
在服務(wù)器返回 或 錯(cuò)誤代碼的情況下,高級(jí)客戶端嘗試分析響應(yīng)正文錯(cuò)誤詳細(xì)信息,然后引發(fā)泛型,并將原始代碼添加為抑制異常。4xx 5xx ElasticsearchExceptionResponseException
4.2.5 異步執(zhí)行
- 也可以以異步方式執(zhí)行 ,以便客戶端可以直接返回。用戶需要指定如何通過(guò)將請(qǐng)求和偵聽(tīng)器傳遞到異步刪除索引方法來(lái)處理響應(yīng)或潛在故障:
DeleteIndexRequest
client.indices().deleteAsync(request, RequestOptions.DEFAULT, listener); //<1>
<1> 執(zhí)行完成時(shí)要執(zhí)行和要使用的DeleteIndexRequest ActionListener
異步方法不會(huì)阻止并立即返回。完成后,如果執(zhí)行成功完成,則使用 ActionListener#onResponse
方法調(diào)用 ,如果執(zhí)行失敗,則使用 ActionListener#
onFailure
該方法。失敗方案和預(yù)期異常與同步執(zhí)行案例相同。
典型的偵聽(tīng)器如下所示:delete-index
ActionListener<AcknowledgedResponse> listener =
new ActionListener<AcknowledgedResponse>() {
@Override
public void onResponse(AcknowledgedResponse deleteIndexResponse) {
//成功執(zhí)行時(shí)調(diào)用。
}
@Override
public void onFailure(Exception e) {
//當(dāng)整個(gè)失敗時(shí)調(diào)用。DeleteIndexRequest
}
};
4.2.6 刪除索引響應(yīng)
- 返回的允許檢索有關(guān)執(zhí)行操作的信息,如下所示:
DeleteIndexResponse
boolean acknowledged = deleteIndexResponse.isAcknowledged(); //<1> 指示所有節(jié)點(diǎn)是否都已確認(rèn)請(qǐng)求
<1> 指示所有節(jié)點(diǎn)是否都已確認(rèn)請(qǐng)求
- 如果未找到索引,將引發(fā) :
ElasticsearchException
try {
DeleteIndexRequest request = new DeleteIndexRequest("does_not_exist");
client.indices().delete(request, RequestOptions.DEFAULT);
} catch (ElasticsearchException exception) {
if (exception.status() == RestStatus.NOT_FOUND) {
//如果未找到要?jiǎng)h除的索引,則進(jìn)行""
}
}
如果未找到要?jiǎng)h除的索引,則進(jìn)行""
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)));
//創(chuàng)建請(qǐng)求
GetIndexRequest request = new GetIndexRequest("student");
//<1> 是返回本地信息還是從主節(jié)點(diǎn)檢索狀態(tài)
request.local(false);
//<2> 返回結(jié)果為適合人類的格式
request.humanReadable(true);
try {
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
} catch (IOException e) {
e.printStackTrace();
}
}
4.3.2 索引存在請(qǐng)求
- 高級(jí) REST 客戶端使用 "Index Exists API"。索引名稱是必需的。
GetIndexRequest
GetIndexRequest request = new GetIndexRequest("twitter"); //<1> index 名稱
<1> index 名稱
4.3.3 可選參數(shù)
- 索引存在 API 還接受以下可選參數(shù),通過(guò) :
GetIndexRequest
request.local(false);//<1> 是返回本地信息還是從主節(jié)點(diǎn)檢索狀態(tài)
request.humanReadable(true); //<2> 返回結(jié)果為適合人類的格式
request.includeDefaults(false); //<3> 是否返回每個(gè)索引的所有默認(rèn)設(shè)置
request.indicesOptions(indicesOptions); //<4> 控制如何解析不可用的索引以及如何展開(kāi)通配符表達(dá)式
<1> 是返回本地信息還是從主節(jié)點(diǎn)檢索狀態(tài)<2> 返回結(jié)果為適合人類的格式<3> 是否返回每個(gè)索引的所有默認(rèn)設(shè)置<4> 控制如何解析不可用的索引以及如何展開(kāi)通配符表達(dá)式
4.3.4 同步執(zhí)行
- 以下列方式執(zhí)行 時(shí),客戶端將等待 返回 ,然后再繼續(xù)執(zhí)行代碼:
GetIndexRequest
boolean
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
與其他同步的相同
4.3.5 異步執(zhí)行
-
- 也可以以異步方式執(zhí)行 ,以便客戶端可以直接返回。用戶需要指定如何通過(guò)將請(qǐng)求和偵聽(tīng)器傳遞到異步索引存在的方法來(lái)處理響應(yīng)或潛在故障:
GetIndexRequest
client.indices().existsAsync(request, RequestOptions.DEFAULT, listener);//<1>執(zhí)行完成時(shí)要執(zhí)行和要使用的 GetIndexRequest ActionListener
<1>執(zhí)行完成時(shí)要執(zhí)行和要使用的
GetIndexRequest
ActionListener
異步的處理邏輯與其他異步的相同,都是實(shí)現(xiàn)ActionListener
的方法
4.3.6 響應(yīng)
- 響應(yīng)是一個(gè)值,指示索引(或索引)是否存在。
boolean
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)));
//創(chuàng)建請(qǐng)求, 參數(shù)index名稱
IndexRequest request = new IndexRequest("student");
//請(qǐng)求的模式,CREATE: 創(chuàng)建模式,如果已經(jīng)存在則報(bào)錯(cuò) Index:存在則不再創(chuàng)建,也不報(bào)錯(cuò)
request.opType(DocWriteRequest.OpType.INDEX); String json = "{n" +
" "id": 12,n" +
" "name": "admin",n" +
" "content": "步的處理邏輯與其他異步的相同,都是實(shí)現(xiàn)ActionListener 的方法"n" +
"}";
request.id("1").source(
json, XContentType.JSON ); IndexResponse indexResponse = null;
try {
//調(diào)用 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 索引請(qǐng)求
- 需要以下參數(shù):
IndexRequest
//創(chuàng)建請(qǐng)求, 參數(shù)index名稱
IndexRequest request = new IndexRequest("student"); //<1> index 名稱
String json = "{n" +
" "id": 12,n" +
" "name": "admin",n" +
" "content": "步的處理邏輯與其他異步的相同,都是實(shí)現(xiàn)ActionListener 的方法"n" +
"}";
request .id("1") // <2> 指定文檔 ID
.source( json, XContentType.JSON // <3> 指定參數(shù)類型,json
);
<1> index 名稱指數(shù)
<2> 請(qǐng)求的文檔 ID
<3> 指定參數(shù)類型,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);
文檔源作為 自動(dòng)轉(zhuǎn)換為
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);
文檔源作為對(duì)象提供,彈性搜索內(nèi)置幫助器生成
JSON
內(nèi)容XContentBuilder
IndexRequest indexRequest = new IndexRequest("student")
.id("1")
.source("id", 1,
"name", "admin",
"content", "trying out Elasticsearch");
作為密鑰對(duì)提供的文檔源,該源將轉(zhuǎn)換為 JSON 格式Object
5.1.3 可選參數(shù)
- 可以選擇提供以下參數(shù):
request.routing("routing"); //<1>
<1> 路由值
request.timeout(TimeValue.timeValueSeconds(1)); //<1>
request.timeout("1s"); // <2>
<1> 超時(shí)以等待主分片 作為 TimeValue<2> 超時(shí)以等待主分片 作為 String
request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL); //<1>
request.setRefreshPolicy("wait_for"); //<2>
<1> 將策略刷新 為實(shí)例
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> 提供的操作類型可以是 或(默認(rèn))String
create
index
request.setPipeline("pipeline");
在索引文檔之前要執(zhí)行的包含管道的名稱
5.1.4 同步執(zhí)行
- 以下列方式執(zhí)行 時(shí),客戶端將等待 返回 ,然后再繼續(xù)執(zhí)行代碼:
IndexRequest
IndexResponse
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
- 同步調(diào)用可能會(huì)引發(fā) 在高級(jí) REST 客戶端中無(wú)法解析 REST 響應(yīng)、請(qǐng)求會(huì)發(fā)出時(shí)間或類似情況下沒(méi)有從服務(wù)器返回的響應(yīng)的情況下。
IOException
- 在服務(wù)器返回 或 錯(cuò)誤代碼的情況下,高級(jí)客戶端嘗試分析響應(yīng)正文錯(cuò)誤詳細(xì)信息,然后引發(fā)泛型,并將原始代碼添加為抑制異常。
4xx 5xx ElasticsearchExceptionResponseException
5.1.5 異步執(zhí)行
- 也可以以異步方式執(zhí)行 ,以便客戶端可以直接返回。用戶需要指定如何通過(guò)將請(qǐng)求和偵聽(tīng)器傳遞到異步索引方法來(lái)處理響應(yīng)或潛在故障:
IndexRequest
client.indexAsync(request, RequestOptions.DEFAULT, listener); //<1>
<1> 執(zhí)行完成時(shí)要執(zhí)行和要使用的
IndexRequest
ActionListener
- 異步方法不會(huì)阻止并立即返回。完成后,如果執(zhí)行成功完成,則使用 方法調(diào)用 ,如果執(zhí)行失敗,則使用 該方法。失敗方案和預(yù)期異常與同步執(zhí)行案例相同。
ActionListener
onResponse
onFailure
- 典型的偵聽(tīng)器如下所示:index
listener = new ActionListener<IndexResponse>() {
@Override
public void onResponse(IndexResponse indexResponse) {
//<1> 成功執(zhí)行時(shí)調(diào)用。
}
@Override
public void onFailure(Exception e) {
//<2> 當(dāng)整個(gè)失敗時(shí)調(diào)用。IndexRequest
}
};
<1> 成功執(zhí)行時(shí)調(diào)用。
<2> 當(dāng)整個(gè)失敗時(shí)調(diào)用。> IndexRequest
5.1.6 索引響應(yīng)
- 返回的允許檢索有關(guān)執(zhí)行操作的信息,如下所示:
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> 處理(如果需要)首次創(chuàng)建文檔的情況
<2> 處理(如果需要)文檔被重寫(xiě)的情況,因?yàn)樗呀?jīng)存在
<3> 處理成功分片數(shù)少于總分片的情況
<4> 處理潛在的故障
- 如果存在版本沖突,將引發(fā) :
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> 引發(fā)異常指示返回版本沖突錯(cuò)誤
- 在設(shè)置為且已存在具有相同索引和 ID 的文檔的情況下,將發(fā)生相同的情況:
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>引發(fā)異常指示返回版本沖突錯(cuò)誤
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 結(jié)果
System.out.println(documentFields.getSource()); // 獲取源作為 Map
System.out.println(documentFields.getSourceAsMap()); // 獲取源作為 bytes
System.out.println(documentFields.getSourceAsBytes()); }else {
System.out.println("不錯(cuò)在該數(shù)據(jù)");
} } catch (IOException e) {
e.printStackTrace(); } }
5.2.2 獲取請(qǐng)求
- 需要以下參數(shù):GetRequest
GetRequest getRequest = new GetRequest(
"posts", //<1>
"1"); //<1>
<1> 索引名稱
<2> 文檔 ID
5.2.3 可選參數(shù)
- 可以選擇提供以下參數(shù):
request.fetchSourceContext(FetchSourceContext.DO_NOT_FETCH_SOURCE);
禁用源檢索,默認(rèn)情況下啟用
String[] includes = new String[]{"message", "*Date"};
String[] excludes = Strings.EMPTY_ARRAY;
FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes);
request.fetchSourceContext(fetchSourceContext);
為特定字段 配置 源包含
includes
: 檢索結(jié)果所包含的字段excludes
: 檢索結(jié)果排除的字段
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();
為特定存儲(chǔ)字段配置檢索(要求字段單獨(dú)存儲(chǔ)在映射中)
檢索存儲(chǔ)的字段(要求該字段單獨(dú)存儲(chǔ)在映射中)message
request.routing("routing");
路由值
request.preference("preference");
首選項(xiàng)值
request.realtime(false);
將實(shí)時(shí)標(biāo)志設(shè)置為(默認(rèn)情況下)falsetrue
request.refresh(true);
在檢索文檔之前執(zhí)行刷新(默認(rèn)情況下)false
request.version(2);
版本
request.versionType(VersionType.EXTERNAL);
版本類型
5.2.4 同步執(zhí)行
- 以下列方式執(zhí)行 時(shí),客戶端將等待 返回 ,然后再繼續(xù)執(zhí)行代碼:
GetRequest
GetResponse
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
-
同步調(diào)用可能會(huì)引發(fā) 在高級(jí) REST 客戶端中無(wú)法解析 REST 響應(yīng)、請(qǐng)求會(huì)發(fā)出時(shí)間或類似情況下沒(méi)有從服務(wù)器返回的響應(yīng)的情況下。IOException
-
在服務(wù)器返回 或 錯(cuò)誤代碼的情況下,高級(jí)客戶端嘗試分析響應(yīng)正文錯(cuò)誤詳細(xì)信息,然后引發(fā)泛型,并將原始代碼添加為抑制異常。4xx5xxElasticsearchExceptionResponseException
5.2.5 異步執(zhí)行
- 也可以以異步方式執(zhí)行 ,以便客戶端可以直接返回。用戶需要指定如何通過(guò)將請(qǐng)求和偵聽(tīng)器傳遞到異步獲取方法來(lái)處理響應(yīng)或潛在故障:
GetRequest
client.getAsync(request, RequestOptions.DEFAULT, listener);
執(zhí)行完成時(shí)要執(zhí)行和要使用的
GetRequest
ActionListener
-
異步方法不會(huì)阻止并立即返回。完成后,如果執(zhí)行成功完成,則使用 方法調(diào)用 ,如果執(zhí)行失敗,則使用 該方法。失敗方案和預(yù)期異常與同步執(zhí)行案例相同。ActionListeneronResponseonFailure
-
典型的偵聽(tīng)器如下所示:
get
ActionListener<GetResponse> listener = new ActionListener<GetResponse>() {
@Override
public void onResponse(GetResponse getResponse) {
//成功執(zhí)行時(shí)調(diào)用
}
@Override
public void onFailure(Exception e) {
//當(dāng)整個(gè)失敗時(shí)調(diào)用。GetRequest
}
};
5.2.6 獲取響應(yīng)
- 返回的允許檢索請(qǐng)求的文檔及其元數(shù)據(jù)和最終存儲(chǔ)的字段。
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> 處理找不到文檔的方案。請(qǐng)注意,盡管返回的響應(yīng)具有狀態(tài)代碼,但返回的是有效的,而不是引發(fā)異常。此類響應(yīng)不保存任何源文檔,其方法將返回。404 GetResponseisExistsfalse
- 當(dāng)對(duì)不存在的索引執(zhí)行 get 請(qǐng)求時(shí),響應(yīng)具有狀態(tài)代碼,即需要按如下方式處理的已引發(fā)請(qǐng)求:
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> 處理引發(fā)異常,因?yàn)樗饕淮嬖? }
}
<1> 處理引發(fā)異常,因?yàn)樗饕淮嬖?/p>
- 如果請(qǐng)求了特定的文檔版本,并且現(xiàn)有文檔具有不同的版本號(hào),則引發(fā)版本沖突:
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> 引發(fā)異常指示返回版本沖突錯(cuò)誤
6. 結(jié)語(yǔ)
其實(shí)很多 Api
的使用都是類似相同的,這里我們不再對(duì)其他 Api
進(jìn)行解析,需要了解的完全可以去光網(wǎng)文檔查看,文檔地址在問(wèn)上漲上面有。
本文由AnonyStar 發(fā)布,可轉(zhuǎn)載但需聲明原文出處。
仰慕「優(yōu)雅編碼的藝術(shù)」 堅(jiān)信熟能生巧,努力改變?nèi)松?br />歡迎關(guān)注微信公賬號(hào) :云棲簡(jiǎn)碼 獲取更多優(yōu)質(zhì)文章
更多文章關(guān)注筆者博客 :云棲簡(jiǎn)碼