ElasticSearch 副本-04Spring Boot 集成 ElasticSearch

Posted touyel

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ElasticSearch 副本-04Spring Boot 集成 ElasticSearch相关的知识,希望对你有一定的参考价值。

kibana 管理 ElasticSearch 索引

1、进入 kibana 首页,点击连接到您的 Elasticsearch 索引

技术图片

2、点击左上角的 ElasticSearch 下的索引管理,进入管理界面

技术图片

Spring Boot 集成 ElasticSearch

官方文档

Elasticsearch Clients

技术图片

我们选择第一个: Java REST Client

技术图片

我们一般使用高级客户端:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html

技术图片

我们可以找到 Maven 依赖:

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-getting-started-maven.html

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.6.2</version>
</dependency>

创建 Spring Boot 项目

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.13.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.touyel.lesson</groupId>
    <artifactId>elasticsearch-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>elasticsearch-api</name>
    <description>elasticsearch-api</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

主要添加这两个依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>

注意一个版本坑

Spring Boot 默认继承的 ElasticSearch 的版本较低

技术图片

我们需要自定义 ElasticSearch 版本:

<properties>
    <java.version>1.8</java.version>
    <!-- 修改成自己对应的版本号 -->
    <elasticsearch.version>7.6.2</elasticsearch.version>
</properties>

更新依赖,确定版本一致!

技术图片

ElasticSearch

新建一个 ElasticSearch 配置类:

package com.touyel.lesson.elasticsearch.config;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author touyel
 */
@Configuration
public class ElasticSearchConfiguration {

    // https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-getting-started-initialization.html
    @Bean
    public RestHighLevelClient restHighLevelClient() {
        return new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("192.168.59.130", 9200, "http")
                )
        );
    }
}

Spring Boot 关于 ElasticSearch 索引的操作

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/_index_apis.html

创建索引

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-create-index.html

/**
 * @author touyel
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class ElasticSearchTest {

    @Resource
    private RestHighLevelClient client;


    // 测试 创建索引
    @Test
    public void testCreateIndex() throws IOException {
        // 1、创建索引请求
        CreateIndexRequest indexRequest = new CreateIndexRequest("touyel");

        // 2、客户端执行请求并获取响应
        CreateIndexResponse response = client.indices().create(indexRequest, RequestOptions.DEFAULT);

        System.out.println(response);
    }
}


/** 运行结果
org.elasticsearch.client.indices.CreateIndexResponse@cc58e9e5
 */

到 kibana 查看(查看方法见顶部【kibana 管理 ElasticSearch 索引】):

技术图片

判断索引是否存在

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-indices-exists.html

@Test
public void testExistsIndex() throws IOException {
     GetIndexRequest indexRequest = new GetIndexRequest("touyel");

     boolean exists = client.indices().exists(indexRequest, RequestOptions.DEFAULT);

     System.out.println(exists);
}

/** 运行结果
true
*/

获取索引信息

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-get-index.html

@Test
public void testGetIndex() throws IOException {
    GetIndexRequest indexRequest = new GetIndexRequest("touyel");

    GetIndexResponse response = client.indices().get(indexRequest, RequestOptions.DEFAULT);

    System.out.println(response.getSettings());
    System.out.println(response.getMappings());
    System.out.println(response.getIndices());
    System.out.println(response.getDefaultSettings());
    System.out.println(response.getAliases());
}

/** 运行结果
{touyel={"index.creation_date":"1587639746159","index.number_of_replicas":"1","index.number_of_shards":"1","index.provided_name":"touyel","index.uuid":"R8GlvkkVRxav3r991A5JHQ","index.version.created":"7060299"}}
{touyel=org.elasticsearch.cluster.metadata.MappingMetaData@7e87ed6e}
[Ljava.lang.String;@d5556bf
{}
{touyel=[]}
*/

删除索引

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-delete-index.html

@Test
public void testDeleteIndex() throws IOException {
    DeleteIndexRequest indexRequest = new DeleteIndexRequest("touyel");

    AcknowledgedResponse delete = client.indices().delete(indexRequest, RequestOptions.DEFAULT);

    System.out.println(delete.isAcknowledged());
}

/** 运行结果
true
*/

Spring Boot 关于 ElasticSearch 文档的操作

先创建一个实体类:

/**
 * @author touyel
 */
@Data
@Component
@Accessors(chain = true)
public class User {

    private String name;
    private Integer age;
    private Date birth;
}

创建索引库:

CreateIndexRequest indexRequest = new CreateIndexRequest("touyel");
CreateIndexResponse response = client.indices().create(indexRequest, RequestOptions.DEFAULT);

测试添加文档

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-index.html

因为我们需要将对象转为 json,所以使用 Jackson 的 ObjectMapper 来转换。

private ObjectMapper mapper = new ObjectMapper();
@Test
public void testCreateDoc() throws IOException {
    // 实例化对象
    User user = new User()
            .setName("二两")
            .setAge(3)
            .setBirth(new Date());

    // 创建请求
    IndexRequest request = new IndexRequest("touyel");

    // 规则
    request.id("1");
    request.timeout(TimeValue.timeValueSeconds(2));

    // 将数据放入请求 json 格式
    request.source(mapper.writeValueAsString(user), XContentType.JSON);

    // 发送请求并获取响应结果
    IndexResponse response = client.index(request, RequestOptions.DEFAULT);

    System.out.println("status: " + response.status());
    System.out.println(response.toString());
}

/** 运行结果
status: CREATED
IndexResponse[index=touyel,type=_doc,id=1,version=1,result=created,seqNo=0,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}]
*/

通过 kibana 查看:

技术图片

判断是否存在文档

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-exists.html

@Test
public void testExistsDoc() throws IOException {
    GetRequest request = new GetRequest("touyel", "1");

    // 不获取返回的 _source 的上下文
    request.fetchSourceContext(new FetchSourceContext(false));

    boolean exists = client.exists(request, RequestOptions.DEFAULT);

    System.out.println(exists);
}

/** 运行结果
true
*/

获取文档信息

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-get.html

@Test
public void testGetDoc() throws IOException {
    GetRequest request = new GetRequest("touyel", "1");

    GetResponse response = client.get(request, RequestOptions.DEFAULT);

    // 打印文档内容
    System.out.println(response.getSourceAsString());

    System.out.println(response);
}

/** 运行结果
{"name":"二两","age":3,"birth":1587642901327}
{"_index":"touyel","_type":"_doc","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"name":"二两","age":3,"birth":1587642901327}}
*/

更新文档

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-update.html

 @Test
public void testUpdateDoc() throws IOException {
    User user = new User()
            .setName("穷鬼二两")
            .setAge(18);

    UpdateRequest request = new UpdateRequest("touyel", "1");

    request.timeout("1s");

    // 在 doc 里面填入更新的内容
    request.doc(mapper.writeValueAsString(user), XContentType.JSON);

    UpdateResponse response = client.update(request, RequestOptions.DEFAULT);

    System.out.println("status: " + response.status());
    System.out.println(response);
}

/** 运行结果
status: OK
UpdateResponse[index=touyel,type=_doc,id=1,version=2,seqNo=1,primaryTerm=1,result=updated,shards=ShardInfo{total=2, successful=1, failures=[]}]
*/

技术图片

删除文档记录

@Test
public void testDeleteDoc() throws IOException {
    DeleteRequest request = new DeleteRequest("touyel", "1");

    DeleteResponse delete = client.delete(request, RequestOptions.DEFAULT);

    System.out.println("status: " + delete.status());
    System.out.println(delete);
}

/** 运行结果
status: OK
DeleteResponse[index=touyel,type=_doc,id=1,version=3,result=deleted,shards=ShardInfo{total=2, successful=1, failures=[]}]
*/

批量插入数据

@Test
public void testBulkCreateDoc() throws IOException {
    BulkRequest request = new BulkRequest();
    request.timeout(TimeValue.timeValueSeconds(20));

    ArrayList<User> users = new ArrayList<>();
    users.add(new User().setName("Rain").setAge(18).setBirth(new Date()));
    users.add(new User().setName("Jack").setAge(22).setBirth(new Date()));
    users.add(new User().setName("Tom").setAge(19).setBirth(new Date()));
    users.add(new User().setName("Jim").setAge(25).setBirth(new Date()));
    users.add(new User().setName("Seeker").setAge(31).setBirth(new Date()));

    for (int i = 0; i < users.size(); i++) {
        request.add(new IndexRequest("touyel")
                .id("" + i + 1)
                .source(mapper.writeValueAsString(users.get(i)), XContentType.JSON));
    }

    BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);

    System.out.println("是否失败: " + response.hasFailures());
    System.out.println(response);
}

/** 运行结果
是否失败: false
org.elasticsearch.action.bulk.BulkResponse@2740e316
*/

技术图片

查询

精确查询:

@Test
public void testSearch() throws IOException {
    SearchRequest request = new SearchRequest("touyel");

    // 构建搜索条件
    SearchSourceBuilder builder = new SearchSourceBuilder();

    // 查询条件可以使用 QueryBuilders 工具来实现
    TermQueryBuilder termQuery = QueryBuilders.termQuery("age", 18);

    builder.query(termQuery);

    builder.timeout(TimeValue.timeValueSeconds(60));

    request.source(builder);

    SearchResponse response = client.search(request, RequestOptions.DEFAULT);

    SearchHit[] hits = response.getHits().getHits();
    for (SearchHit hit : hits) {
        System.out.println(hit.getSourceAsMap());
    }
}

/** 运行结果
{name=Rain, birth=1587645483838, age=18}
*/

高亮查询:

@Test 
public void testSearch() throws IOException {
    SearchRequest request = new SearchRequest("touyel");

    // 构建搜索条件
    SearchSourceBuilder builder = new SearchSourceBuilder();

    // 查询条件可以使用 QueryBuilders 工具来实现
    MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "Jim");

    builder.query(queryBuilder);
    builder.highlighter(new HighlightBuilder().field("name"));

    builder.timeout(TimeValue.timeValueSeconds(60));

    request.source(builder);

    SearchResponse response = client.search(request, RequestOptions.DEFAULT);

    SearchHit[] hits = response.getHits().getHits();
    for (SearchHit hit : hits) {
        System.out.println("高亮字段: " + hit.getHighlightFields());
        System.out.println(hit.getSourceAsMap());
    }
}

/** 运行结果
高亮字段: {name=[name], fragments[[<em>Jim</em>]]}
{name=Jim, birth=1587645483838, age=25}
*/

以上是关于ElasticSearch 副本-04Spring Boot 集成 ElasticSearch的主要内容,如果未能解决你的问题,请参考以下文章

ElasticSearch数据副本模型

Elasticsearch 分片和副本搜索性能

Elasticsearch 中的分片和副本

Spring Boot教程整合elk

ElasticSearch 副本-01ES 概述及安装

Elasticsearch 7.x 之节点集群分片及副本