springboot集成elasticsearch7.17.3

文章目录

    • 一、依赖配置
      • 1、引入es依赖
      • 2、配置文件application.yaml
    • 二、使用Repository对es增删改查
      • 1、定义实体类 Book
      • 2、注解:
          • `@Document`
          • `@Id`
          • `@Field`
      • 3、创建接口 BookRepository
      • 4、创建 BookController
      • 5、Es创建查询机制
      • 6、查询创建机制关键词
          • And
          • Or
          • Is
          • Not
          • Between
          • LessThan
          • LessThanEqual
          • GreaterThan
          • GreaterThanEqual
          • Before
          • After
          • Like
          • StartingWith
          • EndingWith
          • Contanins/Containing
          • In(当注释为 FieldType.Keyword 时)
          • In
          • Notln(当注释为 FieldType.Keyword 时)
          • Notln
          • False
          • OrderBy
          • Exists
          • IsNull
          • IsNotNull
          • IsEmpty
          • IsNotEmpty
      • 7、高级查询
    • 二、Es客户端elasticsearchClient
      • 1、创建客户端配置类 `ElasticSearchConfig`
      • 2、增删改查、批量操作


环境:
jdk1.8
springboot: 2.7.0

spring elastisearch官方文档

一、依赖配置

1、引入es依赖

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-data-elasticsearchartifactId>
        dependency>
                
        <dependency>
            <groupId>jakarta.jsongroupId>
            <artifactId>jakarta.json-apiartifactId>
            <version>2.0.1version>
        dependency>

2、配置文件application.yaml

spring:
  elasticsearch:
    uris: http://1.13.152.218:9200
    username:
    password:
    connection-timeout: 10s
  jackson:
    date-format: "yyyy-MM-dd HH:mm:ss"

二、使用Repository对es增删改查

1、定义实体类 Book

package com.zhuang.es.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName="books")
public class Book {
    @Id
    private Long id;

    @Field(type = FieldType.Text)
    private String name;

    @Field(type = FieldType.Text)
    private String summary;

    @Field(type = FieldType.Double)
    private Double price;

    @Field(type = FieldType.Text)
    private String parent;

    private List<Long> list;

    private Map<Long, String> map;

    @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd HH:mm:ss")
    private Date create;
}

2、注解:

@Document

作用:标识要持久化到Elasticsearch的域对象, 如定义索引名
@Document(indexName="books")

@Id

作用:定义标识符 -> 文档id
@Id private Long id;

@Field

作用:对持久化到Elasticsearch域的属性设置, 比如设置对应es中字段的属性类型

type属性类型:

1、如果没有定义属性的type或者type = FieldType.Auto ,会动态映射 type,会在第一次插入数据时动态设置属性类型。如 private String name; 或 如 @Field(type = FieldType.Auto) private String name;

2、如果显示定义了type的类型,那么在项目启动的时候,就会在es中创建定义的类型
@Field(type = FieldType.Text) private String name; 那么name属性在es中的属性类型为text

format日期格式:

1.使用自带的日期格式:format
@Field(type = FieldType.Date, format = DateFormat.date_hour_minute_second) private Date create DateFormat是枚举类型;
2.自定义时间类型:pattern
设置format = DateFormat.custom或 format = DateFormat.none,
如: @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd HH:mm:ss") private Date create;

3、创建接口 BookRepository

继承 ElasticsearchRepository, T为映射的实体类, ID为标记的id类型

package com.zhuang.es.service;

import com.zhuang.es.entity.Book;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface BookRepository extends ElasticsearchRepository<Book, Long> {
}

4、创建 BookController

注入BookRepository bean,调用封装好的增删改查接口

package com.zhuang.es.controller;

import com.zhuang.es.entity.Book;
import com.zhuang.es.service.BookRepository;
import com.zhuang.es.vo.BookVo;
import com.zhuang.es.vo.ResponseVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;

/**
 * @program: mybatis-plus
 * @description:
 * @author: mrzhuang
 * @create: 2022-12-23 21:14
 **/

@RestController
@RequestMapping("/book")
public class BookController {

    @Resource
    BookRepository bookRepository;

    /**
     * 查询全部
     *
     * @return /
     */
    @GetMapping("/findAll")
    public ResponseVo<Iterable<Book>> findAll() {
        Iterable<Book> books = bookRepository.findAll();
        return new ResponseVo<>(books);
    }

    /**
     * 向es中增加book
     *
     * @param book /
     * @return /
     */
    @PostMapping("/add")
    public ResponseVo<Book> addBook(@RequestBody Book book) {
        Book save = bookRepository.save(book);
        return new ResponseVo<>(save);
    }

    /**
     * 根据id查询
     *
     * @param id /
     * @return /
     */
    @GetMapping("/findById")
    public ResponseVo<Optional<Book>> findById(@RequestParam("id") Long id) {
        Optional<Book> bookOptional = bookRepository.findById(id);
        return new ResponseVo<>(bookOptional);

    }

    /**
     * 通过传入实体删除
     *
     * @param book /
     * @return /
     */
    @PostMapping("/delete")
    public ResponseVo<Boolean> delete(@RequestBody Book book) {
        bookRepository.delete(book);
        return new ResponseVo<>(true);
    }

    /**
     * 通过id删除
     *
     * @param id /
     * @return /
     */
    @GetMapping("/deleteById")
    public ResponseVo<Boolean> delete(@RequestParam("id") Long id) {
        bookRepository.deleteById(id);
        return new ResponseVo<>(true);
    }

  /**
     * 更新某个属性值(如:name)
     * @param bookVo /
     */
    @PostMapping("/update")
    public ResponseVo<Book> update(@RequestBody BookVo bookVo) {
        //获取需要更新的文档id
        Long id = bookVo.getId();
        Optional<Book> option = bookRepository.findById(id);
        if (option.isPresent()) {
            Book book = option.get();
            if (StringUtils.isNotEmpty(bookVo.getName())) {
                book.setName(bookVo.getName());
            }
            Book save = bookRepository.save(book);
            return new ResponseVo<>(book);
        }
        return new ResponseVo<>(CodeEnum.FAILUIRE.code, "更新失败!");
    }

    /**
     * 统计数量
     *
     * @return /
     */
    @GetMapping("/count")
    public ResponseVo<Long> count() {
        long count = bookRepository.count();
        return new ResponseVo<>(count);
    }

    /**
     * 查看id是否存在
     * @param id /
     * @return /
     */
    @GetMapping("/existsById")
    public ResponseVo<Boolean> update(@RequestParam("id") Long id) {
        boolean exists = bookRepository.existsById(id);
        return new ResponseVo<>(exists);
    }

    /**
     * 根据name和price查询
     * @param name /
     * @param price /
     * @return /
     */
    @GetMapping("/findByNameAndPrice")
    public ResponseVo<List<Book>> findByNameAndPrice(@RequestParam("name") String name, @RequestParam("price") Double price) {
        List<Book> books = bookRepository.findByNameAndPrice(name, price);
        return new ResponseVo<>(books);
    }

    /**
     * 根据summary和parent查询
     * @param summary /
     * @param parent /
     * @return /
     */
    @GetMapping("/findBySummaryAndParent")
    public ResponseVo<List<Book>> findBySummaryAndParent(@RequestParam("summary") String summary, @RequestParam("parent") String parent) {
        List<Book> books = bookRepository.findBySummaryAndParent(summary, parent);
        return new ResponseVo<>(books);
    }
    

}

5、Es创建查询机制

通常,Elasticsearch 的查询创建机制按照查询方法中的描述工作。

以下是 Elasticsearch 查询方法转换成的简短示例:
增加方法: List findByNameAndPrice(String name, Double price);
上面的方法名会被翻译成下面的 Elasticsearch json 查询:

{
    "query": {
        "bool" : {
            "must" : [
                { "query_string" : { "query" : "?", "fields" : [ "name" ] } },
                { "query_string" : { "query" : "?", "fields" : [ "price" ] } }
            ]
        }
    }
}
package com.zhuang.es.service;

import com.zhuang.es.entity.Book;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import java.util.List;

public interface BookRepository extends ElasticsearchRepository<Book, Long> {
    List<Book> findByNameAndPrice(String name, Double price);
}

controller层中调用

    @PostMapping("/findByNameAndPrice")
    public ResponseVo<List<Book>> findByNameAndPrice(@RequestParam("name") String name, @RequestParam("price") Double price){
        List<Book> books = bookRepository.findByNameAndPrice(name, price);
        return new ResponseVo<>(books);
    }
springboot集成elasticsearch7.17.3_第1张图片

6、查询创建机制关键词

And
关键词 样本
And findByNameAndPrice

Es 查询字符串:

"bool" : {
"must" : [
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } },
{ "query_string" : { "query" : "?", "fields" : [ "price" ] } }
]
}
}}
Or
关键词 样本
Or findByNameOrPrice

Es 查询字符串:

{ "query" : {
"bool" : {
"should" : [
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } },
{ "query_string" : { "query" : "?", "fields" : [ "price" ] } }
]
}
}}
Is
关键词 样本
Is findByName

Es 查询字符串:

{ "query" : {
"bool" : {
"must" : [
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } }
]
}
}}
Not
关键词 样本
Not findByNameNot

Es 查询字符串:

{ "query" : {
  "bool" : {
  "must_not" : [
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } }
]
}
}}
Between
关键词 样本
Between findByPriceBetween

Es 查询字符串:

{ "query" : {
"bool" : {
"must" : [
{"range" : {"price" : {"from" : ?, "to" : ?, "include_lower" : true, "include_upper" : true } } }
]
}
}}
LessThan
关键词 样本
LessThan findByPriceLessThan

Es 查询字符串:

{ "query" : {
"bool" : {
"must" : [
{"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : false } } }
]
}
}}
LessThanEqual
关键词 样本
LessThanEqual findByPriceLessThanEqual

Es 查询字符串:

{ "query" : {
"bool" : {
"must" : [
{"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : true } } }
]
}
}}
GreaterThan
关键词 样本
GreaterThan findByPriceGreaterThan

Es 查询字符串:

{ "query" : {
"bool" : {
"must" : [
{"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : false, "include_upper" : true } } }
]
}
}}
GreaterThanEqual
关键词 样本
GreaterThanEqual findByPriceGreaterThan

Es查询字符串:

{ "query" : {
"bool" : {
"must" : [
{"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : true, "include_upper" : true } } }
]
}
}}
Before
关键词 样本
Before findByPriceBefore

Es 查询字符串:

{ "query" : {
"bool" : {
"must" : [
{"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : true } } }
]
}
}}
After
关键词 样本
After findByPriceAfter

Es 查询字符串:

{ "query" : {
"bool" : {
"must" : [
{"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : true, "include_upper" : true } } }
]
}
}}
Like
关键词 样本
Like findByNameLike

Es查询字符串

{ "query" : {
"bool" : {
"must" : [
{ "query_string" : { "query" : "?*", "fields" : [ "name" ] }, "analyze_wildcard": true }
]
}
}}
StartingWith
关键词 样本
StartingWith findByNameStartingWith

Es 查询字符串:

{ "query" : {
"bool" : {
"must" : [
{ "query_string" : { "query" : "?*", "fields" : [ "name" ] }, "analyze_wildcard": true }
]
}
}}
EndingWith
关键词 样本
EndingWith findByNameEndingWith

Es查询字符串

{ "query" : {
"bool" : {
"must" : [
{ "query_string" : { "query" : "*?", "fields" : [ "name" ] }, "analyze_wildcard": true }
]
}
}}
Contanins/Containing
关键词 样本
Contains/Containing findByNameContaining

Es 查询字符串:

{ "query" : {
"bool" : {
"must" : [
{ "query_string" : { "query" : "*?*", "fields" : [ "name" ] }, "analyze_wildcard": true }
]
}
}}
In(当注释为 FieldType.Keyword 时)
关键词 样本
In(当注释为 FieldType.Keyword 时) findByNameIn(Collectionnames)

Es 查询字符串:

{ "query" : {
"bool" : {
"must" : [
{"bool" : {"must" : [
{"terms" : {"name" : ["?","?"]}}
]
}
}
]
}
}}
In
关键词 样本
In findByNameIn(Collectionnames)

Es 查询字符串:

{ "query": {"bool": {"must": [{"query_string":{"query": "\"?\" \"?\"", "fields": ["name"]}}]}}}
Notln(当注释为 FieldType.Keyword 时)
关键词 样本
NotIn(当注释为 FieldType.Keyword 时) indByNameNotIn(Collectionnames)

Es 查询字符串:

{ "query" : {
"bool" : {
"must" : [
{"bool" : {"must_not" : [
{"terms" : {"name" : ["?","?"]}}
]
}
}
]
}
}}
Notln
关键词 样本
NotIn findByNameNotIn(Collectionnames)

Es 查询字符串:

{"query": {"bool": {"must": [{"query_string": {"query": "NOT(\"?\" \"?\")", "fields": ["name"]}}]}}}
关键词 | 样本
--- | ----
True|findByAvailableTrue

{ "query" : {
"bool" : {
"must" : [
{ "query_string" : { "query" : "true", "fields" : [ "available" ] } }
]
}
}}
False
关键词 样本
False findByAvailableFalse

Es 查询字符串:

{ "query" : {
"bool" : {
"must" : [
{ "query_string" : { "query" : "false", "fields" : [ "available" ] } }
]
}
}}
OrderBy
关键词 样本
OrderBy findByAvailableTrueOrderByNameDesc

Es 查询字符串:

{ "query" : {
"bool" : {
"must" : [
{ "query_string" : { "query" : "true", "fields" : [ "available" ] } }
]
}
}, "sort":[{"name":{"order":"desc"}}]
}
Exists
关键词 样本
Exists findByNameExists

Es 查询字符串:

{"query":{"bool":{"must":[{"exists":{"field":"name"}}]}}}
IsNull
关键词 样本
IsNull findByNameIsNull

Es 查询字符串:

{"query":{"bool":{"must_not":[{"exists":{"field":"name"}}]}}}
IsNotNull
关键词 样本
IsNotNull findByNameIsNotNull

Es 查询字符串:

{"query":{"bool":{"must":[{"exists":{"field":"name"}}]}}}
IsEmpty
关键词 样本
IsEmpty findByNameIsEmpty

Es 查询字符串:

{"query":{"bool":{"must":[{"bool":{"must":[{"exists":{"field":"name"}}],"must_not":[{"wildcard":{"name":{"wildcard":"*"}}}]}}]}}}
IsNotEmpty
关键词 样本
IsNotEmpty findByNameIsNotEmpty

Es 查询字符串:

{"query":{"bool":{"must":[{"wildcard":{"name":{"wildcard":"*"}}}]}}}	

7、高级查询

注入 ElasticsearchOperations bean

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.query_dsl.BoolQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.MatchAllQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch._types.query_dsl.TermQuery;
import co.elastic.clients.json.JsonData;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhuang.es.EsApplication;
import com.zhuang.es.entity.Book;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import org.springframework.data.elasticsearch.client.elc.NativeQueryBuilder;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHits;

import javax.annotation.Resource;

/**
 * @program: mybatis-plus
 * @description:
 * @author: mrzhuang
 * @create: 2022-12-22 21:43
 **/

@Slf4j
@SpringBootTest(classes = EsApplication.class)
public class EsTest {
    @Resource
    ElasticsearchOperations operations;

    @Test
    public void testSearch() {
        //term查询
        TermQuery termQuery = new TermQuery.Builder().field("price").value("10.2").build();
        Query tQuery = new Query.Builder().term(termQuery).build();
        //等同于lambda表达式
        Query price2 = new Query.Builder().term(t -> t.field("price").value("10.2")).build();

        BoolQuery boolQuery = new BoolQuery.Builder()
                //filter
                .filter(q -> q.range(r -> r.field("price").gte(JsonData.of(11.0)).lt(JsonData.of(16.0))))
                //matchAll
                .must(q -> q.matchAll(new MatchAllQuery.Builder().build())).build();

        NativeQuery nativeQuery = new NativeQueryBuilder().withQuery(q -> q.bool(boolQuery))
                //查询结果按照price从小到大排序
                .withSort(Sort.by(Sort.Direction.ASC, "price"))
                //第0页开始
                .withPageable(PageRequest.of(0, 5))
                .build();
        SearchHits search = operations.search(nativeQuery, Book.class);
        search.stream().forEach(System.out::println);

    }
}

二、Es客户端elasticsearchClient

1、创建客户端配置类 ElasticSearchConfig

package com.zhuang.es.config;

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 lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.message.BasicHeader;
import org.elasticsearch.client.Node;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;

import javax.annotation.Resource;

@Configuration
@Slf4j
public class ElasticSearchConfig extends ElasticsearchConfigurationSupport {
    @Resource
    private ElasticsearchProperties elasticSearchProperty;
 
    @Bean
    public RestClientBuilder restClientBuilder() {
        return RestClient.builder(elasticSearchProperty.getUris().stream().map(this::getElasticSearchHttpHosts).toArray(HttpHost[]::new)).
                setRequestConfigCallback(requestConfigBuilder -> {
                    //设置连接超时时间
                    requestConfigBuilder.setConnectTimeout(elasticSearchProperty.getConnectionTimeout().toMillisPart());
                    requestConfigBuilder.setSocketTimeout(elasticSearchProperty.getSocketTimeout().toMillisPart());
                    return requestConfigBuilder;
                }).setFailureListener(new RestClient.FailureListener() {
                    //某节点失败,这里可以做一些告警
                    @Override
                    public void onFailure(Node node) {
                        log.error("[ ElasticSearchClient ] >>  node :{}, host:{},  fail ", node.getName(), node.getHost());
                    }
                }).setHttpClientConfigCallback(httpClientBuilder -> {
                    // 设置[X-Elastic-Product] header
                    httpClientBuilder.disableAuthCaching().addInterceptorLast((HttpResponseInterceptor)(response, context) -> response.addHeader("X-Elastic-Product", "Elasticsearch"));

                    //设置账密
                    return getHttpAsyncClientBuilder(httpClientBuilder);
                });
    }
 
 
    /**
     * 配置es client
     */
    @Bean(value = "elasticsearchClient")
    public ElasticsearchClient elasticsearchClient(@Qualifier("restClientBuilder") RestClientBuilder restClientBuilder) {
        RestClient restClient = restClientBuilder.setDefaultHeaders(new Header[]{new BasicHeader("Content-Type", "application/json")}).build();
        ElasticsearchTransport transport = new RestClientTransport(
                restClient, new JacksonJsonpMapper());
        return new ElasticsearchClient(transport);
    }
 
    @Bean(value = "elasticsearchTemplate")
    public ElasticsearchTemplate elasticsearchTemplate(ElasticsearchClient elasticsearchClient, ElasticsearchConverter elasticsearchConverter) {
        return new ElasticsearchTemplate(elasticsearchClient, elasticsearchConverter);
    }
 
    private HttpHost getElasticSearchHttpHosts(String host) {
        host = host.replaceAll("http://", "").replaceAll("https://", "");
        return new HttpHost(host.split(":")[0], Integer.parseInt(host.split(":")[1]), "http");
    }
 
 
    private HttpAsyncClientBuilder getHttpAsyncClientBuilder(HttpAsyncClientBuilder httpClientBuilder) {
        if (StringUtils.isEmpty(elasticSearchProperty.getUsername()) || StringUtils.isEmpty(elasticSearchProperty.getPassword())) {
            return httpClientBuilder;
        }
        //设置账号密码
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(elasticSearchProperty.getUsername(), elasticSearchProperty.getPassword()));
        httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
        return httpClientBuilder;
    }
}

2、增删改查、批量操作

注入ElasticsearchClient bean

   @Resource(name = "elasticsearchClient")
   ElasticsearchClient client;
package com.zhuang;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
import co.elastic.clients.elasticsearch.core.bulk.IndexOperation;
import co.elastic.clients.elasticsearch.core.bulk.UpdateOperation;
import co.elastic.clients.elasticsearch.indices.CreateIndexRequest;
import co.elastic.clients.elasticsearch.indices.CreateIndexResponse;
import com.zhuang.es.EsApplication;
import com.zhuang.es.entity.Book;
import com.zhuang.es.service.BookRepository;
import com.zhuang.es.vo.BookVo;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;

/**
 * @program: kafka
 * @description:
 * @author: mrzhuang
 * @create: 2022-12-25 13:04
 **/
@Slf4j
@SpringBootTest(classes = EsApplication.class)
public class EsClientTest {

    @Resource
    BookRepository repository;
    @Resource(name = "elasticsearchClient")
    ElasticsearchClient client;

    /**
     * 创建索引
     * @throws IOException
     */
    @Test
    void testCreateIndex() throws IOException {
        //client.indices().create(c->c.index("book"));
        CreateIndexRequest createIndexRequest= new CreateIndexRequest.Builder().index("book").build();
        CreateIndexResponse indexResponse = client.indices().create(createIndexRequest);
        log.info("[{}]索引创建[{}]!", indexResponse.index(), indexResponse.shardsAcknowledged());
    }

    /**
     * 增加数据
     * @throws IOException
     */
    @Test
    void testInsertData() throws IOException {
        Optional<Book> book = repository.findById(1l);
        IndexRequest<Book> indexRequest = new IndexRequest.Builder<Book>().index("book").id("1").document(book.isPresent() ? book.get() : Book.builder().name("小刘").id(2l).build()).build();
        //IndexRequest source = indexRequest.index("book").id("1").source(book.isPresent() ? book.get() : Book.builder().name("小刘"));
        IndexResponse index = client.index(indexRequest);
        log.info("向索引[{}]中增加id:[{}]文档:[{}]", index.index(), index.id(), index.result());
    }
    /**
     * 删除数据
     * @throws IOException /
     */
    @Test
    void testDeleteData() throws IOException {
        //1.根据id删除
        DeleteRequest deleteRequest = new DeleteRequest.Builder().index("book").id("gAcXSIUB94FMQr43ryS6").build();
        DeleteResponse deleteResponse = client.delete(deleteRequest);
        log.info("根据id删除:{}", deleteResponse.result().jsonValue());


        //2.根据查询条件删除
        DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest.Builder().index(List.of("book")).query(q -> q.term(t -> t.field("name").value("xiaoxiao"))).build();
        DeleteByQueryResponse deleteByQueryResponse = client.deleteByQuery(deleteByQueryRequest);
        log.info("根据查询条件删除:{}个", deleteByQueryResponse.total());
    }

    /**
     * 更新数据
     *
     * @throws IOException
     */
    @Test
    void testUpdateDate() throws IOException {
        //方法1:创建实体类BookVo对应的实体类的属性和名称与Book相同
        //会将Book中对应的属性值替换为需要修改的bookVo中的属性值,然后更新es相对应的属性值
        BookVo bookVo = BookVo.builder().parent("妈").build();
        UpdateRequest<Book, BookVo> update1 = new UpdateRequest.Builder<Book, BookVo>().index("book").id("1").doc(bookVo).build();

        //方法2:创建Map
        Map<String, String > map = new HashMap<>();
        map.put("parent","爸妈");
        UpdateRequest<Book, Map<String, String >> update2 = new UpdateRequest.Builder<Book, Map<String, String >>().index("book").id("1").doc(map).build();

        UpdateResponse<Book> update = client.update(update1, Book.class);
        log.info("update:{}", update.result());
    }
    /**
     * 查询数据
     * @throws IOException
     */
    @Test
    void testSearch() throws IOException {
        TermQuery termQuery = new TermQuery.Builder().field("id").value("11").build();
        Query query = new Query.Builder().term(termQuery).build();
        BoolQuery boolQuery = new BoolQuery.Builder().must(query).build();
        Query build = new Query.Builder().bool(boolQuery).build();
        SearchRequest searchRequest = new SearchRequest.Builder().query(build).index(Arrays.asList(new String[]{"book"})).build();

        SearchResponse<Book> response = client.search(searchRequest, Book.class);
        log.info("查询数据:{}", response.hits().hits().size());
    }

    /**
     * 批量增加
     * @throws IOException
     */
    @Test
    void testBulkInsert() throws IOException {
        //批量新增数据
        //第一个数据
        IndexOperation<Book> indexOperation1 = new IndexOperation.Builder<Book>().id("2").document(Book.builder().id(2l).name("小庄呀").build()).build();
        BulkOperation operation1 = new BulkOperation.Builder().index(indexOperation1).build();
        //第二个数据
        IndexOperation<Book> indexOperation2 = new IndexOperation.Builder<Book>().id("3").document(Book.builder().id(3l).name("小庄呀").build()).build();
        BulkOperation operation2 = new BulkOperation.Builder().index(indexOperation1).build();

        List<BulkOperation> operations = new ArrayList<>();
        operations.add(operation1);
        operations.add(operation2);

        BulkRequest bulkRequest = new BulkRequest.Builder().index("book").operations(operations).build();
        BulkResponse bulkResponse = client.bulk(bulkRequest);
        log.info("批量删除:{}, size:{}", !bulkResponse.errors(), bulkResponse.items().size());
    }

    /**
     * 批量更新
     * @throws IOException
     */
    @Test
    void testBulkUpdate() throws IOException {
        //批量新增数据
        //第一个数据
        UpdateOperation<Book, BookVo> updateOperation1 = new UpdateOperation.Builder<Book, BookVo>().id("2").action(b -> b.doc(BookVo.builder().name("xiaoxiao").build())).build();
        BulkOperation operation1 = new BulkOperation.Builder().update(updateOperation1).build();

        //第一个数据
        UpdateOperation<Book, BookVo> updateOperation2 = new UpdateOperation.Builder<Book, BookVo>().id("3").action(b -> b.doc(BookVo.builder().name("xiao").build())).build();
        BulkOperation operation2= new BulkOperation.Builder().update(updateOperation2).build();

        List<BulkOperation> operations = new ArrayList<>();
        operations.add(operation1);
        operations.add(operation2);

        BulkRequest bulkRequest = new BulkRequest.Builder().index("book").operations(operations).build();
        BulkResponse bulkResponse = client.bulk(bulkRequest);
        log.info("批量更新:{}, size:{}", !bulkResponse.errors(), bulkResponse.items().size());
    }
}

你可能感兴趣的:(spring,boot,elasticsearch,java)