您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > JAVA

一文读懂 Java操作Elasticsearch

时间:2020-10-12 09:39:48  来源:  作者:

一文读懂 Java操作Elasticsearch

 

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 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 发布,可转载但需声明原文出处。
仰慕「优雅编码的艺术」 坚信熟能生巧,努力改变人生
欢迎关注微信公账号 :云栖简码 获取更多优质文章
更多文章关注笔者博客 :云栖简码



Tags:Elasticsearch   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
一、环境准备1.1、环境列表 节点名称 系统 ip地址 es-node1 centos7.6 192.168.10.128 es-node2 centos7.6 ...【详细内容】
2021-07-03  Tags: Elasticsearch  点击:(117)  评论:(0)  加入收藏
Elasticsearch(简称ES) 是一个分布式、高扩展、高实时的搜索与数据分析引擎,它也是一个“存储库”。它能很方便地使大量数据具有搜索、分析和探索的能力。充分利用 ES 的水平伸...【详细内容】
2021-06-22  Tags: Elasticsearch  点击:(89)  评论:(0)  加入收藏
作者:LX 一、 环境搭建 1、 启动Spark集群服务 1)启动Spark集群 2)子节点加入集群 3)查看是否加入成功 2、启动Elasticsearch数据库 1)可以启动自己安装的Elasticsearch数据库...【详细内容】
2021-06-11  Tags: Elasticsearch  点击:(132)  评论:(0)  加入收藏
环境:elasticsearch7.8.0索引模板通过事先定义好的模板,在创建索引时,如果索引名称与模版中定义的索引模式匹配那么就会自动应用模版中的配置信息。如果有多个索引模板被匹配,那...【详细内容】
2021-05-27  Tags: Elasticsearch  点击:(203)  评论:(0)  加入收藏
作者:中华石杉来源:石杉的架构笔记(ID:shishan100)目录:1. 一道面试题的引入:2. 性能优化的杀手锏:Filesystem Cache3. 数据预热4. 冷热分离5. ElasticSearch 中的关联查询6. Docum...【详细内容】
2021-03-04  Tags: Elasticsearch  点击:(133)  评论:(0)  加入收藏
基本概念定义 一个分布式的实时文档存储,每个字段 可以被索引与搜索 一个分布式实时分析搜索引擎 能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据用途 ...【详细内容】
2020-11-09  Tags: Elasticsearch  点击:(119)  评论:(0)  加入收藏
时下不论是在全文搜索领域还是大数据即时处理领域ELK都一枝独秀,而ELK的核心在于Elasticsearch,ELK很秀源于Elasticsearch很棒。很多可能用过ELK但是对其核心Elasticsearch却...【详细内容】
2020-10-26  Tags: Elasticsearch  点击:(80)  评论:(0)  加入收藏
1. 简述 Elasticsearch 是基于 Lucene 开发的一个分布式全文检索框架,向 Elasticsearch 中存储和从 Elasticsearch 中查询,格式是json。 向 Elasticsearch 中存储数据,其实...【详细内容】
2020-10-12  Tags: Elasticsearch  点击:(58)  评论:(0)  加入收藏
Elasticsearch作为一门全文检索技术,那它是如何使用的呢? 先学习Elasticsearch的一些语法,后续再在项目中实战应用。一、IK分词器这个IK分词器有什么用?为什么要用它?要知道计算...【详细内容】
2020-09-18  Tags: Elasticsearch  点击:(115)  评论:(0)  加入收藏
随着移动互联网、物联网、云计算等信息技术蓬勃发展,数据量呈爆炸式增长。如今我们可以轻易得从海量数据里找到想要的信息,其中离不开搜索引擎技术的帮助。...【详细内容】
2020-09-11  Tags: Elasticsearch  点击:(114)  评论:(0)  加入收藏
▌简易百科推荐
一、Redis使用过程中一些小的注意点1、不要把Redis当成数据库来使用二、Arrays.asList常见失误需求:把数组转成list集合去处理。方法:Arrays.asList 或者 Java8的stream流式处...【详细内容】
2021-12-27  CF07    Tags:Java   点击:(3)  评论:(0)  加入收藏
文章目录 如何理解面向对象编程? JDK 和 JRE 有什么区别? 如何理解Java中封装,继承、多态特性? 如何理解Java中的字节码对象? 你是如何理解Java中的泛型的? 说说泛型应用...【详细内容】
2021-12-24  Java架构师之路    Tags:JAVA   点击:(5)  评论:(0)  加入收藏
大家好!我是老码农,一个喜欢技术、爱分享的同学,从今天开始和大家持续分享JVM调优方面的经验。JVM调优是个大话题,涉及的知识点很庞大 Java内存模型 垃圾回收机制 各种工具使用 ...【详细内容】
2021-12-23  小码匠和老码农    Tags:JVM调优   点击:(11)  评论:(0)  加入收藏
前言JDBC访问Postgresql的jsonb类型字段当然可以使用Postgresql jdbc驱动中提供的PGobject,但是这样在需要兼容多种数据库的系统开发中显得不那么通用,需要特殊处理。本文介绍...【详细内容】
2021-12-23  dingle    Tags:JDBC   点击:(12)  评论:(0)  加入收藏
Java与Lua相互调用案例比较少,因此项目使用需要做详细的性能测试,本内容只做粗略测试。目前已完成初版Lua-Java调用框架开发,后期有时间准备把框架进行抽象,并开源出来,感兴趣的...【详细内容】
2021-12-23  JAVA小白    Tags:Java   点击:(10)  评论:(0)  加入收藏
Java从版本5开始,在 java.util.concurrent.locks包内给我们提供了除了synchronized关键字以外的几个新的锁功能的实现,ReentrantLock就是其中的一个。但是这并不意味着我们可...【详细内容】
2021-12-17  小西学JAVA    Tags:JAVA并发   点击:(10)  评论:(0)  加入收藏
一、概述final是Java关键字中最常见之一,表示“最终的,不可更改”之意,在Java中也正是这个意思。有final修饰的内容,就会变得与众不同,它们会变成终极存在,其内容成为固定的存在。...【详细内容】
2021-12-15  唯一浩哥    Tags:Java基础   点击:(14)  评论:(0)  加入收藏
1、问题描述关于java中的日志管理logback,去年写过关于logback介绍的文章,这次项目中又优化了下,记录下,希望能帮到需要的朋友。2、解决方案这次其实是碰到了一个问题,一般的情况...【详细内容】
2021-12-15  软件老王    Tags:logback   点击:(17)  评论:(0)  加入收藏
本篇文章我们以AtomicInteger为例子,主要讲解下CAS(Compare And Swap)功能是如何在AtomicInteger中使用的,以及提供CAS功能的Unsafe对象。我们先从一个例子开始吧。假设现在我们...【详细内容】
2021-12-14  小西学JAVA    Tags:JAVA   点击:(21)  评论:(0)  加入收藏
一、概述观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监听者,类似监听器的存在,一旦被观察/监听的目标发生的情况,就会被监听者发现,这么想来目标发生情况到观察...【详细内容】
2021-12-13  唯一浩哥    Tags:Java   点击:(16)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条