网络知识 娱乐 springboot集成elasticsearch 8.0以上版本

springboot集成elasticsearch 8.0以上版本

        现在的elasticsearch已经更新到8.2版本,网络上的学习资料基本都是8.0以下的版本。elasticsearch官方在8.0版本以后,已经舍弃了High level rest clint Api,推荐使用java clint api。所以再参照8.0以下版本的资料进行学习已经非常不适合。依据如下图1-1:

图1-1

        由于本人在学习过程中,查找网上学习资料都是8.0以下的资料,许多地方都不适用,非常痛苦。所以在此记录本人在学习过程中的知识,以便后面学习8.0以上版本的同学有个参照的资料。

        elasticsearch的下载安装基本都差不多,这里就不过多赘述,直接从springboot集成elasticsearch开始

安装依赖

        新建springboot项目,在pom.xml文件中添加依赖,这里使用的es版本是8.1.1版本,各位道友使用8.0以上版本均可,将8.1.1替换成你本地下载的es版本就行。

        
            co.elastic.clients
            elasticsearch-java
            8.1.1
        
        
            org.jsoup
            jsoup
            1.10.2
        

        本人完整的pom.xml依赖

    

    4.0.0
    com.ck.nbplus.elasticsearch
    elasticsearch
    0.0.1-SNAPSHOT
    elasticsearch
    Demo project for Spring Boot

    
        1.8
        8.1.1
        UTF-8
        UTF-8
        2.3.7.RELEASE
    

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

        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
            
                
                    org.junit.vintage
                    junit-vintage-engine
                
            
        
        
            co.elastic.clients
            elasticsearch-java
            8.1.1
        
        
            jakarta.json
            jakarta.json-api
            2.0.1
        
    

    
        
            
                org.springframework.boot
                spring-boot-dependencies
                ${spring-boot.version}
                pom
                import
            
        
    

    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                3.8.1
                
                    1.8
                    1.8
                    UTF-8
                
            
            
                org.springframework.boot
                spring-boot-maven-plugin
                2.3.7.RELEASE
                
                    com.ck.nbplus.elasticsearch.elasticsearch.ElasticsearchApplication
                
                
                    
                        repackage
                        
                            repackage
                        
                    
                
            
        
    

        不建议直接复制,建议以官方文档为准,参照官方文档学习收获更大,不管版本怎么变都可以适应。官方文档地址:Installation | Elasticsearch Java API Client [8.2] | Elastic (加载很慢,可能加载好几遍才出来)

封装工具类

        新建EsUtilConfigClint工具类

package com.ck.nbplus.elasticsearch.elasticsearch.esutil;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
@Configuration
public class EsUtilConfigClint {
    /**
     * 客户端
     * @return
     * @throws IOException
     */
    public ElasticsearchClient configClint() throws IOException {
        // Create the low-level client
        RestClient restClient = RestClient.builder(
                new HttpHost("127.0.0.1", 9200)).build();

        // Create the transport with a Jackson mapper
        ElasticsearchTransport transport = new RestClientTransport(
                restClient, new JacksonJsonpMapper());

        // 客户端
        ElasticsearchClient client = new ElasticsearchClient(transport);

        return client;
    }
}

        新建Product实体类

package com.ck.nbplus.elasticsearch.elasticsearch.dao;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Product {
    private String productName;
    private double price;
    private int number;
    public String geIndexId() {
        int id = 1;
        id += id;
        String indesId = String.valueOf(id);
        return indesId;
    }
}

        注意我这里使用lombok,没有的去pom.xml添加依赖,或者自己添加get、set方法。

        
            org.projectlombok
            lombok
            true
        

        测试类中新建ElasticsearchApplicationTests测试类。这里使用测试类方便测试。

        测试类中代码,参照参考文档所写。

package com.ck.nbplus.elasticsearch.elasticsearch;
import co.elastic.clients.elasticsearch._types.query_dsl.MatchQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch._types.query_dsl.RangeQuery;
import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.core.search.TotalHits;
import co.elastic.clients.elasticsearch.core.search.TotalHitsRelation;
import co.elastic.clients.elasticsearch.indices.*;
import co.elastic.clients.elasticsearch.indices.ExistsRequest;
import co.elastic.clients.json.JsonData;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import com.ck.nbplus.elasticsearch.elasticsearch.dao.Product;
import com.ck.nbplus.elasticsearch.elasticsearch.esutil.EsUtilConfigClint;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@SpringBootTest
class ElasticsearchApplicationTests {
    @Autowired
    private EsUtilConfigClint clint;

    /**
     * 判断索引是否存在
     * @throws IOException
     */
    @Test
    void existsIndex() throws IOException {
        ExistsRequest existsRequest = new ExistsRequest.Builder().index("ouldindex").build();
        BooleanResponse existsResponse = clint.configClint().indices().exists(existsRequest);
        System.out.println("是否存在:"+existsResponse.value());
    }
    /**
     * 创建索引
     * 创建索引时,必须是小写,否则创建报错
     * @throws IOException
     */
    @Test
    void createIndex() throws IOException {
        CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index("ouldindex").build();
        CreateIndexResponse createIndexResponse = clint.configClint().indices().create(createIndexRequest);
        System.out.println("是否成功:"+createIndexResponse.acknowledged());
    }

    /**
     * 删除索引
     * @throws IOException
     */
    @Test
    void deleteIndex() throws IOException {
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest.Builder().index("ouldindex").build();
        DeleteIndexResponse deleteIndexResponse = clint.configClint().indices().delete(deleteIndexRequest);
        System.out.println("是否成功:"+deleteIndexResponse.acknowledged());
    }

    /**
     * 同步方式
     * 向索引中添加信息,此操作不存在索引时会直接创建索引,使用时需要各种校验使逻辑更严谨
     * @throws IOException
     */
    @Test
    void setIndex() throws IOException {
        Product product = new Product("帽子",44.5,9);
        IndexRequest indexRequest = new IndexRequest.Builder().index("newindex")
                .id(String.valueOf(product.getNumber()))
                .document(product)
                .build();
        IndexResponse indexResponse = clint.configClint().index(indexRequest);
        System.out.println(indexResponse);
    }

    /**
     * 批量写入数据
     * @throws IOException
     */
    @Test
    void bulkIndex() throws IOException{
        List products = new ArrayList();
        products.add(new Product("香烟",135,1));
        products.add(new Product("瓜子",154,2));
        products.add(new Product("矿泉水",613,3));
        products.add(new Product("酱油",72,4));
        products.add(new Product("大米",771,5));
        BulkRequest.Builder bk = new BulkRequest.Builder();
        int indexId = 4;
        for (Product product:products) {
            bk.operations(op->op.index(i->i.index("newindex")
                    .id(UUID.randomUUID().toString())
                    .document(product)));
        }
        BulkResponse response = clint.configClint().bulk(bk.build());
        if (response.errors()) {
            System.out.println("Bulk had errors");
            for (BulkResponseItem item: response.items()) {
                if (item.error() != null) {
                    System.out.println(item.error().reason());
                }
            }
        }
    }

    /**
     * 根据索引文档id获取文档信息
     * @throws IOException
     */
    @Test
    void getIndexById() throws IOException {
        GetRequest getRequest = new GetRequest.Builder().index("newindex")
                .id("9")
                .build();
        GetResponse response = clint.configClint().get(getRequest, Product.class);
        if (response.found()) {
            Product product = response.source();
            System.out.println("Product name " + product.getNumber());
            System.out.println("Product price " + product.getPrice());
        } else {
            System.out.println("Product not found");
        }
    }

    /**
     * 简单查询文档信息
     * @throws IOException
     */
    @Test
    void getSearch() throws IOException{

        /*此处 .from(1).size(2) 表示分页查询,从第一页开始查询,大小为两条*/
        SearchRequest searchRequest = new SearchRequest.Builder().index("newindex")
                .query(q -> q.match(m -> m.field("productName").query("烟"))).from(1).size(2).build();

        SearchResponse response = clint.configClint().search(searchRequest,Product.class);

        TotalHits total = response.hits().total();
        boolean isExactResult = total.relation() == TotalHitsRelation.Eq;

        if (isExactResult) {
            System.out.println("There are " + total.value() + " results");
        } else {
            System.out.println("There are more than " + total.value() + " results");
        }

        List<Hit> hits = response.hits().hits();
        for (Hit hit: hits) {
            Product product = hit.source();
            System.out.println("Found product " + product.getProductName() + ", score " + hit.score());
        }
    }

    /**
     * 多条件嵌套查询文档信息
     * @throws IOException
     */
    @Test
    void getSearchs() throws IOException{
        String productName = "衣服";
        double price = 115;

        //按照产品名称搜索
        Query byname = MatchQuery.of(m -> m.field("productName")
                .query(productName))._toQuery();

        //按照产品价格搜索
        Query byprice = RangeQuery.of(r -> r
                .field("price")
                .gte(JsonData.of(price))
        )._toQuery();

        //结合名称和价格查询
        SearchResponse response = clint.configClint().search(s -> s
                        .index("newindex")
                        .query(q -> q
                                .bool(b -> b
                                        .must(byname)
                                        .must(byprice)
                                )
                        )
                        .from(1)
                        .size(2),
                Product.class
        );

        List<Hit> hits = response.hits().hits();
        for (Hit hit : hits){
            Product product = hit.source();
            System.out.println(product.getName()+" "+product.getPrice());
        }
    }

}