SpringBoot集成并连接ElasticSearch

761 阅读2分钟

本文详细说明在 MacOS 系统上,如何在 SpringBoot 中集成 ElasticSearch,并用模糊匹配示例展示基本查询使用。

本文对应代码:github.com/houchenll/e…

条件

  • 系统:macOs
  • SpringBoot: 3.3.3
  • ES: 8.14.3

添加 ES 依赖

pom.xml 中添加以下 elasticSearch 依赖,注意版本指定为和 springBoot 相同。

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

添加 ES 配置

预先启动本地ES。

启动安全校验下配置

如果ES启用了安全校验,则配置为,打开 application.yml,添加如下配置。

spring:
  elasticsearch:
    uris: https://localhost:9200    # Elasticsearch 服务器地址
    username: elastic               # 用户名
    password: VwpZZnl012345zwfG8B  # 密码

注意:uris 使用 https。

如果本地ES有 cert 校验,则运行之前,需先把ES证书添加到java sdk的密钥库中,步骤如下:

# 进入 java sdk 证书所在位置
cd /Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home/lib/security
# 执行以下命令,将 ES 的 ca 证书添加到 java sdk 的密钥库中,且取别名为 es_http_ca
sudo keytool -keystore cacerts -importcert -alias "es_http_ca" -file ~/env/elasticsearch-8.14.3/config/certs/http_ca.crt

安装证书时,当需要输入密钥库口令时,使用默认的 changeit。当询问是否信任此证书时,输入 y 并按回车。然后证书就会被添加到密钥库中。

如果不知道本机 jdk 安装位置,可以使用以下命令获取:

# 查看 java 命令位置
which java
# 查看 java 版本
/usr/bin/java --version
# 查看 java 实际安装位置
/usr/libexec/java_home -v 17

禁用安全校验下配置

如果使用项目中 docker-compose.yml 启动项目,docker compose up,且指定禁用安全校验,则上面配置不需要 usernamepassword 两项,且 uris 中的端口需要对应修改为 9920,且 https 换成 http,即 http://localhost:9920。注意,如果 docker 启动失败,需要先删除相关的 docker container。

如果使用普通方式启动ES,如 ./bin/elasticsearch,则禁用安全校验的方式为,打开 ./config/elasticsearch.yml,将 xpack.security.enabled 值设置为 false,然后重新执行 ./bin/elasticsearch

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

定义 ES 文档对应 bean 文件

假设 ES 索引中文档有 texttitle 字段,则定义如下 Bean 文件,将 es document 中的字段和 Bean 中的属性对应起来。

@Document(indexName = "poem-index")
@Data
public class Poem {

    // 对应 document._id,为字符串
    @Id
    private String id;

    // 对应 document._source['title']
    @Field(type = FieldType.Text)
    private String title;

    // 对应 document._source['text']
    @Field(type = FieldType.Text)
    private String text;

}

定义数据操作类

public interface PoemRepository extends ElasticsearchRepository<Poem, String> {
    // 根据text字段模糊匹配
    @Query("{"match": {"text": {"query": "?0"}}}")
    List<Poem> findByText(String text);

    // 根据text和title字段模糊匹配,fuzziness使用"AUTO" 使查询支持模糊匹配,根据查询词的长度自动决定模糊度
    @Query("{"multi_match": {"query": "?0", "fields": ["text", "title"], "fuzziness": "AUTO"}}")
    List<Poem> findByTextOrTitle(String text);
}

定义 service 和 controller

Service

@Service
public class PoemService {

    @Autowired
    private PoemRepository poemRepository;

    public Iterable<Poem> searchAll() {
        return poemRepository.findAll();
    }

    public List<Poem> searchPosts(String query) {
        return poemRepository.findByTextOrTitle(query);
    }

}

Controller

@RestController
@RequestMapping("hello")
public class HelloController {

    @Autowired
    private PoemService poemService;

    @GetMapping("/search/all")
    public Iterable<Poem> searchAll() {
        return poemService.searchAll();
    }

    @GetMapping("/search")
    public List<Poem> search(@RequestParam(name = "query") String query) {
        return poemService.searchPosts(query);
    }

}