首頁 > 軟體

Java操作Elasticsearch 之 [Java High Level REST Clientedit]

2020-09-23 22:32:16

1. 簡述

  • Elasticsearch 是基於 Lucene 開發的一個分散式全文檢索框架,向 Elasticsearch 中儲存和從 Elasticsearch 中查詢,格式是json。

  • Elasticsearch 中儲存資料,其實就是向 es 中的 index 下面的 type 中儲存 json 類型的資料。

  • elasticsearch 提供了很多語言的客戶端用於操作 elasticsearch 服務,例如: javapython.netJavaScriptPHP 等。本文主要介紹如何使用 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 ClientJava 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 10
    • elasticsearch 7.91
    • IDEA
    • Maven
    • Java 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. 初始化

RestHighLevelClient client = new RestHighLevelClient(
        RestClient.builder(
                new HttpHost("localhost", 9200, "http"),
                new HttpHost("localhost", 9201, "http")));
  • 高階客戶端將在內部創建用於基於提供的生成器執行請求的低階客戶端。該低階客戶端維護一個連線池並啟動一些執行緒,因此,當您很好地完成高階客戶端時,您應該關閉該高階客戶端,然後關閉內部低階客戶端以釋放這些資源。這可以通過 以下時間完成: close
client.close();

在有關 Java 高階客戶端的本文件的其餘部分中,例項將引用為 。 RestHighLevelClient client

案例:

  • 查詢 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": 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  //類型對映,需要的是一個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();

對映作為物件提供的源,彈性搜尋內建幫助器,用於生成 JSON 內容 XContentBuilder

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" : 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 可選參數

  • 可以選擇提供以下參數:
request.setTimeout(TimeValue.timeValueMinutes(2));

超時以等待所有節點將索引創建確認為 TimeValue

request.setMasterTimeout(TimeValue.timeValueMinutes(1));

以作為 TimeValue

request.waitForActiveShards(ActiveShardCount.from(2));
request.waitForActiveShards(ActiveShardCount.DEFAULT);

在創建索引 API 返回響應之前等待的活動分片副本數,作為 in t
在創建索引 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 返回 ,然後再繼續執行程式碼: DeleteIndexRequest DeleteIndexResponse
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 同步執行

  • 以下列方式執行 時,客戶端將等待 返回 ,然後再繼續執行程式碼: GetIndexRequest boolean
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);

與其他同步的相同

4.3.5 非同步執行

  • 也可以以非同步方式執行 ,以便客戶端可以直接返回。使用者需要指定如何通過將請求和偵聽器傳遞到非同步索引存在的方法來處理響應或潛在故障: GetIndexRequest
client.indices().existsAsync(request, RequestOptions.DEFAULT, listener);//<1>執行完成時要執行和要使用的 GetIndexRequest  ActionListener

<1>執行完成時要執行和要使用的 GetIndexRequest ActionListener
非同步的處理邏輯與其他非同步的相同,都是實現 ActionListener 的方法

4.3.6 響應

  • 響應是一個值,指示索引(或索引)是否存在。 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)));
        //創建請求, 參數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> 提供的操作類型可以是 或(預設) String create index

request.setPipeline("pipeline");

在索引文件之前要執行的包含管道的名稱

5.1.4 同步執行

  • 以下列方式執行 時,客戶端將等待 返回 ,然後再繼續執行程式碼: IndexRequest IndexResponse
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> 執行完成時要執行和要使用的 IndexRequest ActionListener

  • 非同步方法不會阻止並立即返回。完成後,如果執行成功完成,則使用 方法呼叫 ,如果執行失敗,則使用 該方法。失敗方案和預期異常與同步執行案例相同。 ActionListener onResponse onFailure
  • 典型的偵聽器如下所示:index
listener = new ActionListener<IndexResponse>() {
    @Override
    public void onResponse(IndexResponse indexResponse) {
        //<1> 成功執行時呼叫。
    }

    @Override
    public void onFailure(Exception e) {
        //<2> 當整個失敗時呼叫。IndexRequest
    }
};

<1> 成功執行時呼叫。

<2> 當整個失敗時呼叫。> IndexRequest

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 同步執行

  • 以下列方式執行 時,客戶端將等待 返回 ,然後再繼續執行程式碼: GetRequest GetResponse
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
  • 同步呼叫可能會引發 在高階 REST 客戶端中無法解析 REST 響應、請求會發出時間或類似情況下沒有從伺服器返回的響應的情況下。IOException

  • 在伺服器返回 或 錯誤程式碼的情況下,高階客戶端嘗試分析響應正文錯誤詳細資訊,然後引發泛型,並將原始程式碼新增為抑制異常。4xx5xxElasticsearchExceptionResponseException

5.2.5 非同步執行

  • 也可以以非同步方式執行 ,以便客戶端可以直接返回。使用者需要指定如何通過將請求和偵聽器傳遞到非同步獲取方法來處理響應或潛在故障: GetRequest
client.getAsync(request, RequestOptions.DEFAULT, listener);

執行完成時要執行和要使用的 GetRequest ActionListener

  • 非同步方法不會阻止並立即返回。完成後,如果執行成功完成,則使用 方法呼叫 ,如果執行失敗,則使用 該方法。失敗方案和預期異常與同步執行案例相同。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 釋出,可轉載但需聲明原文出處。
仰慕「優雅編碼的藝術」 堅信熟能生巧,努力改變人生
歡迎關注微信公賬號 :雲棲簡碼 獲取更多優質文章
更多文章關注筆者部落格 :雲棲簡碼


IT145.com E-mail:sddin#qq.com