栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java与es8实战之四:SpringBoot应用中操作es8(无安全检查)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java与es8实战之四:SpringBoot应用中操作es8(无安全检查)

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

本篇概览
  • 本篇是《java与es8实战》系列的第四篇,系列文章写到现在,连个HelloWorld都没运行起来,实在说不过去了…
  • 因此,本篇总体目标明确:实战在SpringBoot应用中操作elasticsearch8
  • 为了降低难度,本篇部署的elasticsearch8未设置安全检查,无需证书、账号、密码,只要连接到es的IP和端口就能执行操作
  • 总体目标可以拆解为两个子任务
  1. 在SpringBoot中连接elasticsearch8
  2. 在SpringBoot中使用elasticsearch8官方的Java API Client
  • 接下来直接开始
部署elasticsearch集群(无安全检查)
  • 关于快速部署elasticsearch集群(无安全检查),可以参考《docker-compose快速部署elasticsearch-8.x集群+kibana》
Java应用连接elasticsearch的核心套路
  • 不论是直连,还是带安全检查的连接,亦或是与SpringBoot的集成使之更方便易用,都紧紧围绕着一个不变的核心套路,该套路由两部分组成,掌握了它们就能在各种条件下成功连接es
  1. 首先,是builder pattern,连接es有关的代码,各种对象都是其builder对象的build方法创建的,建议您提前阅读《java与es8实战之一》一文,看完后,满屏的builder代码可以从丑变成美…
  2. 其次,就是java应用能向es发请求的关键:ElasticsearchClient对象,该对象的创建是有套路的,如下图,先创建RestClient,再基于RestClient创建ElasticsearchTransport,最后基于ElasticsearchTransport创建ElasticsearchClient,这是个固定的套路,咱们后面的操作都是基于此的,可能会加一点东西,但不会改变流程和图中的对象
  • 准备完毕,开始写代码
新建子工程
  • 为了便于管理依赖库版本和源码,《java与es8实战》系列的所有代码都以子工程的形式存放在父工程elasticsearch-tutorials中

  • 《java与es8实战之二:实战前的准备工作》一文说明了创建父工程的详细过程

  • 在父工程elasticsearch-tutorials中新建名为basic-crud的子工程,其pom.xml内容如下




    
    
        elasticsearch-tutorials
        com.bolingcavalry
        1.0-SNAPSHOT
        ../pom.xml
    
    4.0.0
    
    basic-crud
    jar
    
    basic-crud
    https://github.com/zq2599

    
    
        
            
                org.springframework.boot
                spring-boot-dependencies

                ${springboot.version}
                pom
                import
            
        
    

    
        
            org.springframework.boot
            spring-boot-starter-actuator
        

        
        
            org.springframework.boot
            spring-boot-configuration-processor
            true
        

        
            org.projectlombok
            lombok
        

        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-test
            test

            
            
                
                    junit
                    junit
                
            

        

        
        
            org.junit.jupiter
            junit-jupiter-api
            test
        

        
            org.junit.jupiter
            junit-jupiter-engine
            test
        

        
        
            co.elastic.clients
            elasticsearch-java
        

        
            com.fasterxml.jackson.core
            jackson-databind
        

        
        
            jakarta.json
            jakarta.json-api
        

        
            org.springframework.boot
            spring-boot-starter-web
        
    

    
        
            
            
                org.apache.maven.plugins
                maven-surefire-plugin
                3.0.0-M4
                
                    false
                
            

            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        
                            org.projectlombok
                            lombok
                        
                    
                
            
        

        
            
                src/main/resources
                
                    **
    private HttpHost[] toHttpHost() {
        if (!StringUtils.hasLength(hosts)) {
            throw new RuntimeException("invalid elasticsearch configuration");
        }

        String[] hostArray = hosts.split(",");
        HttpHost[] httpHosts = new HttpHost[hostArray.length];
        HttpHost httpHost;
        for (int i = 0; i < hostArray.length; i++) {
            String[] strings = hostArray[i].split(":");
            httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), "http");
            httpHosts[i] = httpHost;
        }

        return httpHosts;
    }

    @Bean
    public ElasticsearchClient elasticsearchClient() {
        HttpHost[] httpHosts = toHttpHost();
        RestClient restClient = RestClient.builder(httpHosts).build();
        RestClientTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
        return new ElasticsearchClient(transport);
    }

    @Bean
    public ElasticsearchAsyncClient elasticsearchAsyncClient() {
        HttpHost[] httpHosts = toHttpHost();
        RestClient restClient = RestClient.builder(httpHosts).build();
        RestClientTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
        return new ElasticsearchAsyncClient(transport);
    }
}
  • 从上面的代码可以看出,配置类已经向Spring容器注册了ElasticsearchClient实例,后面的业务都可以使用此实例来操作ES
编码:服务类
  • 本篇只是为了演示SpringBoot应用如何连接和操作ES,还不会深入ES操作的细节,因此只对索引做一些基本操作即可

  • 先写一个接口IndexService.java,里面定义了多个索引操作的方法

package com.bolingcavalry.basic.service;

import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import co.elastic.clients.elasticsearch.indices.IndexSettings;
import co.elastic.clients.util.ObjectBuilder;

import java.io.IOException;
import java.util.function.Function;

public interface IndexService {

    
    void addIndex(String name) throws IOException;

    
    boolean indexExists(String name) throws IOException;

    
    void delIndex(String name) throws IOException;

    
    void create(String name,
                Function> settingFn,
                Function> mappingFn) throws IOException;
}
  • 然后接口的实现,可见所有操作都是在调用ElasticsearchClient实例的API
package com.bolingcavalry.basic.service.impl;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import co.elastic.clients.elasticsearch.indices.IndexSettings;
import co.elastic.clients.util.ObjectBuilder;
import com.bolingcavalry.basic.service.IndexService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.function.Function;

@Service
public class IndexServiceImpl implements IndexService {

    @Autowired
    private ElasticsearchClient elasticsearchClient;

    @Override
    public void addIndex(String name) throws IOException {
        ApplicationContext applicationContext;
        elasticsearchClient.indices().create(c -> c.index(name));
    }

    @Override
    public boolean indexExists(String name) throws IOException {
        ApplicationContext a;
        return elasticsearchClient.indices().exists(b -> b.index(name)).value();
    }

    @Override
    public void delIndex(String name) throws IOException {
        elasticsearchClient.indices().delete(c -> c.index(name));
    }

    @Override
    public void create(String name,
                       Function> settingFn,
                       Function> mappingFn) throws IOException {
       elasticsearchClient
               .indices()
               .create(c -> c
                       .index(name)
                       .settings(settingFn)
                       .mappings(mappingFn)
               );
    }
}
  • 以上就是本篇的功能代码了,连接ES在其上进行索引相关操作
编码:单元测试
  • 为了验证上述代码是否生效,接下来写一个单元测试类IndexServiceTest.java,可以重点关注createIndex方法,里面演示了Builder pattern构建参数的详细步骤
package com.bolingcavalry.basic.service;

import co.elastic.clients.elasticsearch._types.mapping.Property;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import co.elastic.clients.elasticsearch.indices.IndexSettings;
import co.elastic.clients.util.ObjectBuilder;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.function.Function;

@SpringBootTest
class IndexServiceTest {

    @Autowired
    IndexService indexService;

    @Test
    void addIndex() throws Exception {
        String indexName = "test_index";

        Assertions.assertFalse(indexService.indexExists(indexName));
        indexService.addIndex(indexName);
        Assertions.assertTrue(indexService.indexExists(indexName));
        indexService.delIndex(indexName);
        Assertions.assertFalse(indexService.indexExists(indexName));
    }

    @Test
    void indexExists() throws Exception {
        indexService.indexExists("a");
    }

    @Test
    void createIndex() throws Exception {
        // 索引名
        String indexName = "product002";

        // 构建setting时,builder用到的lambda
        Function> settingFn = sBuilder -> sBuilder
                .index(iBuilder -> iBuilder
                        // 三个分片
                        .numberOfShards("3")
                        // 一个副本
                        .numberOfReplicas("1")
                );

        // 新的索引有三个字段,每个字段都有自己的property,这里依次创建
        Property keywordProperty = Property.of(pBuilder -> pBuilder.keyword(kBuilder -> kBuilder.ignoreAbove(256)));
        Property textProperty = Property.of(pBuilder -> pBuilder.text(tBuilder -> tBuilder));
        Property integerProperty = Property.of(pBuilder -> pBuilder.integer(iBuilder -> iBuilder));

        // // 构建mapping时,builder用到的lambda
        Function> mappingFn = mBuilder -> mBuilder
                .properties("name", keywordProperty)
                .properties("description", textProperty)
                .properties("price", integerProperty);

        // 创建索引,并且指定了setting和mapping
        indexService.create(indexName, settingFn, mappingFn);
    }
}
  • 确保不做安全检查的ES集群运行正常,再执行单元测试,如下图,顺利通过,证明所有对ES的操作都符合预期
  • 再用eshead观察product002索引的情况,如下图,三个分片,一个副本,与代码中设置的一致
  • 至此最简单的连接和操作ES实战已经完成,希望本篇能给您一些参考,助您顺利完成基本操作
是不是线程安全的
  • 官方回应:https://discuss.elastic.co/t/is-elasticsearch-client-is-thread-safe/151745
  • 有人在问这个问题,es团队的成员Simon Willnauer的回答是:java的client肯定是线程安全的,golang的不清楚
  • 对我来说,有他这话就够了,至于golang的嘛,在本文就不讨论了
源码下载
  • 本篇实战的完整源码可在GitHub下载到,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos)
名称链接备注
项目主页https://github.com/zq2599/blog_demos该项目在GitHub上的主页
git仓库地址(https)https://github.com/zq2599/blog_demos.git该项目源码的仓库地址,https协议
git仓库地址(ssh)git@github.com:zq2599/blog_demos.git该项目源码的仓库地址,ssh协议
  • 这个git项目中有多个文件夹,本次实战的源码在elasticsearch-tutorials文件夹下,如下图红框
  • elasticsearch-tutorials是个父工程,里面有多个module,本篇实战的module是basic-crud,如下图红框
你不孤单,欣宸原创一路相伴
  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 数据库+中间件系列
  6. DevOps系列
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1002623.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号