环境说明:jdk1.8、springboot2.6.13、elasticsearch7.10.2

# 1、Springboot导入ES依赖


 <!-- Spring Data Elasticsearch -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.elasticsearch.client</groupId>
                    <artifactId>elasticsearch-rest-high-level-client</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.elasticsearch</groupId>
                    <artifactId>elasticsearch</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.10.2</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.10.2</version>
        </dependency>

首先了解一下版本兼容问题,官方地址:Springboot-es Versions
需要先剔除默认es客户端(7.15.2),再导入与本地客户端相对应的版本(我是7.10.2)
查看是否冲突,如下图所示
QQ截图20240717211256.png

# 2、连接ES客户端

方法一:application.yml文件配置

spring:
  elasticsearch:
    uris: http://localhost:9200

方法二:自定义config文件

@Configuration
public class ElasticsearchConfig {

    @Value("${spring.elasticsearch.uris}")
    private String elasticsearchUri;

    @Bean
    public RestHighLevelClient restHighLevelClient() {
        return new RestHighLevelClient(
                RestClient.builder(HttpHost.create(elasticsearchUri)));
    }
}

# 3、简单测试

entity创建实体类MyDocument

  • indexName 为索引
  • shards 主分片、replicas 副本分片
  • Field 字段类型、索引分词类型、搜索分词类型

(7.x版本以下没有@Setting,使用@Document(indexName = "my_index_1",shards =1))

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;

@Data
@Document(indexName = "my_index_1")
@Setting(shards = 1,replicas = 0)
public class MyDocument {

    @Id
    private String id;

    @Field(type = FieldType.Text ,analyzer = "ik_max_word",searchAnalyzer = "ik_smart")
    private String title;

    @Field(type = FieldType.Text ,analyzer = "ik_max_word",searchAnalyzer = "ik_smart")
    private String content;

    @Field(type = FieldType.Text ,analyzer = "ik_max_word",searchAnalyzer = "ik_smart")
    private String tag;
}

dao包创建MyDocumentRepository类(该类会自动检测并作为一个bean注册到Spring容器中)


import com.my.blog.entity.MyDocument;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface MyDocumentRepository extends ElasticsearchRepository<MyDocument, String> {
}

common包创建IndexInitializer 类,该类在启动springboot项目时自动生成es索引(相当于mysql的表),生成的字段和映射以实体类配置为准。【如果不需要自动生成,或者已经手动命令生成,再或者需要再业务中才生成,可忽略该类】

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.stereotype.Component;

@Component
public class IndexInitializer implements ApplicationListener<ContextRefreshedEvent> {

    private final ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Autowired
    public IndexInitializer(ElasticsearchRestTemplate elasticsearchRestTemplate) {
        this.elasticsearchRestTemplate = elasticsearchRestTemplate;
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        ensureIndexesExist();
    }

    private void ensureIndexesExist() {
        // 这里列出所有需要生成索引的类
        ensureIndexExists(MyDocument.class);
    }

    private void ensureIndexExists(Class<?> documentClass) {
        IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(documentClass);
        if (!indexOperations.exists()) {
            //创建索引
            indexOperations.create();
            //创建映射
            indexOperations.putMapping();
        }
    }
}

controller包创建MyDocumentController类,(这里测试忽略service层,直接调用dao层接口)

import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

import static org.elasticsearch.index.query.QueryBuilders.multiMatchQuery;

@RestController
@RequestMapping("/doc")
public class MyDocumentController {


    @Autowired
    private MyDocumentRepository repository;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

// 新增或者修改: http://localhost:8081/doc/save?id=1&content=1111&title=2222&tag=有趣
    @PostMapping("/save")
    public MyDocument save(MyDocument document) {
        return repository.save(document);
    }

//  按id查询  http://localhost:8081/doc/1
    @GetMapping("/{id}")
    public MyDocument findById(@PathVariable String id) {
        return repository.findById(id).get();
    }

// 按id删除   http://localhost:8081/doc/d/1
    @DeleteMapping("/d/{id}")
    public void deleteById(@PathVariable String id) {
        repository.deleteById(id);
    }

//  索引中匹配text数据  http://localhost:8081/doc/f?text=1111
    @GetMapping("/f")
    public List<MyDocument> findByContent(String text) {
        // 创建一个NativeSearchQueryBuilder实例
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

        // 添加multi_match查询,搜索title和content字段
        queryBuilder.withQuery(
                multiMatchQuery(text)
                        .field("title") // 指定搜索title字段
                        .field("content") // 指定搜索content字段
                        .field("tag") // 指定搜索tag字段
                        .type(MultiMatchQueryBuilder.Type.BEST_FIELDS) // 设置multi_match查询类型
        );

        // 设置分页信息,例如获取前10条记录
        queryBuilder.withPageable(PageRequest.of(0, 10));

        // 构建最终的SearchQuery对象
        NativeSearchQuery build = queryBuilder.build();

        // 使用ElasticsearchRestTemplate执行查询
        SearchHits<MyDocument> search = elasticsearchRestTemplate.search(queryBuilder.build(), MyDocument.class);
        List<MyDocument> documents = search.getSearchHits()
                .stream()
                .map(hit -> hit.getContent())
                .collect(Collectors.toList());

        return documents;
    }

}