跳至主要內容

SpringBoot集成Elasticsearch

Zenghr大约 3 分钟

SpringBoot集成Elasticsearch

SpringBoot默认支持两种技术来和 ES 交互;

  • Jest(默认不生效)
    • 需要导入jest的工具包(io.searchbox.client.JestClient)
    • 从springboot 2.2.0以后被弃用
  • SpringData ElasticSearch

版本适配说明:

参考地址:https://github.com/spring-projects/spring-data-elasticsearch/blob/main/src/main/asciidoc/preface.adocopen in new window

Spring Data Release TrainSpring Data ElasticsearchElasticsearchSpring FrameworkSpring Boot
2021.14.3.x7.13.45.3.x2.5.x
2021.0 (Pascal)4.2.x7.12.05.3.x2.5.x
2020.0 (Ockham)4.1.x7.9.35.3.22.4.x
Neumann4.0.x7.6.25.2.122.3.x
Moore3.2.x6.8.125.2.122.2.x
Lovelace3.1.x6.2.25.1.192.1.x
Kay3.0.x5.5.05.0.132.0.x
Ingalls2.1.x2.4.04.3.251.5.x

配置环境

提示

开发环境配置如下👇

框架版本
SpringBoot2.5.3
Elasticsearch7.14.0
Spring Data Elasticsearch4.2.3

导入 pom 文件

我们想要在 SpringBoot 中集成 Elasticsearch,第一步☝️就是导入相应的 pom 文件

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

配置文件

# 全文搜索配置
spring:
  elasticsearch:
    rest:
      uris: http://localhost:9200

默认的地址就是:http://localhost:9200open in new window 如果你的端口地址不一致或者你设置了账号密码验证,需要配置你的信息

开启注解

@EnableElasticsearchRepositories(basePackages = "xx.xxx.xxx")

因为使用了 Spring-data 框架,所以需要开启注解扫描 Repository 类

编写对应的 JavaBean

先定义一个 JavaBean 类,指定索引名和 类型(type 即将废用)

注意:SpringBoot启动时会自动创建映射,但要注意如果已经存在相同的index

@Data
@Document(indexName = "strategy_es")
public class StrategyEs {
    //@Field 每个文档的字段配置(类型、是否分词、是否存储、分词器 )
    @Id
    @Field(store = true, index = false, type = FieldType.Long)
    private Long id;  // 攻略id

    @Field(analyzer = "ik_max_word", store = true, searchAnalyzer = "ik_max_word", type = FieldType.Text)
    private String title;  // 攻略标题

    @Field(analyzer = "ik_max_word", store = true, searchAnalyzer = "ik_max_word", type = FieldType.Text)
    private String subTitle;  // 攻略标题

    @Field(analyzer = "ik_max_word", store = true, searchAnalyzer = "ik_max_word", type = FieldType.Text)
    private String summary; // 攻略简介
}

@Documnet 注解

public @interface Document {
    // 索引名称
    String indexName();
    @Deprecated
    boolean useServerConfiguration() default false;
    @Deprecated
    short shards() default 1;
    @Deprecated
    short replicas() default 1;
    @Deprecated
    String refreshInterval() default "1s";
    @Deprecated
    String indexStoreType() default "fs";
    boolean createIndex() default true;
    VersionType versionType() default VersionType.EXTERNAL;
}

@Field 注解

public @interface Field {
    @AliasFor("name")
    String value() default "";
    @AliasFor("value")
    String name() default "";
	// 自动检测属性的类型,可以根据实际情况自己设置
    FieldType type() default FieldType.Auto;
	// 默认情况下分词,一般默认分词就好,除非这个字段你确定查询时不会用到
    boolean index() default true;
	// 时间格式化
    DateFormat[] format() default {DateFormat.date_optional_time, DateFormat.epoch_millis};
	// 默认情况下不存储原文
    boolean store() default false;
	// 指定字段搜索时使用的分词器
    String searchAnalyzer() default "";
	// 指定分词器
    String analyzer() default "";
}

创建 Repository

注意: 没有这一步,即便在实体上方设置@Document,SpringBoot 启动也不会创建 mapping

Spring Data 的强大之处,就在于你不用写任何DAO处理,自动根据方法名或类的信息进行CRUD操作。只要你定义一个接口,然后继承Repository提供的一些子接口,就能具备各种基本的CRUD功能

@Repository
public interface StrategyEsRepository extends ElasticsearchRepository<StrategyEs, Long> {
}

映射结构如下👇

{
  "mappings": {
    "_doc": {
      "properties": {
        "_class": {
          "type": "keyword",
          "index": false,
          "doc_values": false
        },
        "id": {
          "type": "keyword"
        },
        "subTitle": {
          "type": "text",
          "store": true,
          "analyzer": "ik_max_word"
        },
        "summary": {
          "type": "text",
          "store": true,
          "analyzer": "ik_max_word"
        },
        "title": {
          "type": "text",
          "store": true,
          "analyzer": "ik_max_word"
        }
      }
    }
  }
}

Crud 操作

public class ElasticsearchTest {
    @Autowired
    private StrategyEsRepository strategyEsRepository;
    
    @Test
    void createStrategyEsTest() {
        StrategyEs strategyEs = new StrategyEs();
        // 添加 and 修改
        strategyEsRepository.save(strategyEs);
        strategyEsRepository.deleteById(1L);
        strategyEsRepository.delete(strategyEs);
    }
}

ElasticsearchRestTemplate

ES有两个模板,分别为ElasticsearchRestTemplateElasticsearchTemplate

分别对应于High Level REST ClientTransport Client(弃用),两个模板都实现了ElasticsearchOperations接口,由于 ElasticsearchTemplate 弃用,因此使用时我们一般使用 ElasticsearchRestTemplate

注入模板

@Autowired
private ElasticsearchRestTemplate restTemplate;

Crud 索引

@Test
void crudIndexTest() {
    // 创建索引
    restTemplate.indexOps(IndexCoordinates.of("es_test")).create();
    // 索引是否存在
    restTemplate.indexOps(indexCoordinates).exists();
    // 删除索引
    restTemplate.indexOps(indexCoordinates).delete();
}

提示

至此,SpringBoot 集成 Elasticsearch 就算完成了,我们就可以用 Java 代码去操作我们的 Elasticsearch

其中因为 旧版本的 Repository 中的 search 方法被废弃了 ,只能操作简单的 Crud 操作,复杂的查询就需要使用 ElasticsearchRestTemplate 了

如需要查看 Spring Data Elasticsearch 的复杂查询,请看:Elasticsearch - 复杂查询