1 简介

  • 我们的应用经常需要添加检索功能,开源的ElasticSearch是目前全文搜索引擎的首选。它可以快速的存储、搜索和分析海量数据。SpringBoot通过整合Spring Data ElasticSearch为我们提供了非常便捷的检索功能的支持。
  • ElasticSearch是一个分布式搜索功能,提供Restful API,底层基于Lucene,采用多shard(分片)的方式保证数据安全,并且提供自动resharding的功能,github等大型的站点也是采用ElasticSearch作为其搜索服务。

2 概念

2.1 概念

  • 以员工文档的形式存储为例:一个文档代表一个员工数据。存储数据到ElasticSearch的行为叫做索引,但是在索引一个文档之前,需要确定将文档存储在哪里。
  • 一个ElasticSeach集群可以包含多个索引,相应的每个索引可以包含多个类型。这些不同的类型存储着多个文档,每个文档有多个属性。
  • 类似关系:
    • 索引—数据库。
    • 类型—表。
    • 文档—表中记录。
    • 属性—列。

ES概念.png

2.2 应用示例(摘自官网)

  • 对于员工目录,我们将做如下操作:
  • SpringBoot和检索 - 图2每个员工索引一个文档,文档包含该员工的所有信息。
  • SpringBoot和检索 - 图3每个文档都将是 employee 类型
  • SpringBoot和检索 - 图4该类型位于 索引 megacorp 内。
  • SpringBoot和检索 - 图5该索引保存在我们的 Elasticsearch 集群中。
  • 实践中这非常简单(尽管看起来有很多步骤),我们可以通过一条命令完成所有这些动作:
  1. PUT /megacorp/employee/1
  2. {
  3. "first_name" : "John",
  4. "last_name" : "Smith",
  5. "age" : 25,
  6. "about" : "I love to go rock climbing",
  7. "interests": [ "sports", "music" ]
  8. }
  • 注意,路径 /megacorp/employee/1 包含了三部分的信息:
  • megacorp:索引名称。
  • employee:类型名称。
  • 1:特定雇员的ID。

存储数据到ES中.png

3 SpringBoot整合ElasticSearch

3.1 Docker安装ElasticSearch

  1. docker run -d --name elasticsearch -p 9200:9200 \
  2. -p 9300:9300 \
  3. -e "discovery.type=single-node" \
  4. -e ES_JAVA_OPTS="-Xms256m -Xmx256m" \
  5. -d elasticsearch:7.7.0

3.2 搭建环境

SpringBoot的版本是2.3.4.RELEASE,ES的版本是7.7.0。

  • 导入相关jar包的Maven坐标:
  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-web</artifactId>
  8. </dependency>
  • application.yml
  1. spring:
  2. elasticsearch:
  3. rest:
  4. uris: http://192.168.237.100:9200

3.3 编写实体类

  • Article.java:
  1. package com.sunxiaping.springboot.domain;
  2. import org.springframework.data.annotation.Id;
  3. import org.springframework.data.elasticsearch.annotations.Document;
  4. import java.io.Serializable;
  5. @Document(indexName = "es",type = "_article")
  6. public class Article implements Serializable {
  7. @Id
  8. private Integer id;
  9. private String author;
  10. private String title;
  11. private String content;
  12. public Integer getId() {
  13. return id;
  14. }
  15. public void setId(Integer id) {
  16. this.id = id;
  17. }
  18. public String getAuthor() {
  19. return author;
  20. }
  21. public void setAuthor(String author) {
  22. this.author = author;
  23. }
  24. public String getTitle() {
  25. return title;
  26. }
  27. public void setTitle(String title) {
  28. this.title = title;
  29. }
  30. public String getContent() {
  31. return content;
  32. }
  33. public void setContent(String content) {
  34. this.content = content;
  35. }
  36. @Override
  37. public String toString() {
  38. return "Article{" +
  39. "id=" + id +
  40. ", author='" + author + '\'' +
  41. ", title='" + title + '\'' +
  42. ", content='" + content + '\'' +
  43. '}';
  44. }
  45. }

3.4 编写持久层接口

  • 编写ArticleRepository接口:
  1. package com.sunxiaping.springboot.repository;
  2. import com.sunxiaping.springboot.domain.Article;
  3. import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
  4. public interface ArticleRepository extends ElasticsearchRepository<Article,Integer> {
  5. }

3.5 测试

  1. package com.sunxiaping.springboot;
  2. import com.sunxiaping.springboot.domain.Article;
  3. import com.sunxiaping.springboot.repository.ArticleRepository;
  4. import org.junit.Test;
  5. import org.junit.runner.RunWith;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.boot.test.context.SpringBootTest;
  8. import org.springframework.test.context.junit4.SpringRunner;
  9. import java.util.Optional;
  10. @SpringBootTest
  11. @RunWith(SpringRunner.class)
  12. public class SpringbootApplicationTests {
  13. @Autowired
  14. private ArticleRepository articleRepository;
  15. @Test
  16. public void test(){
  17. Article article = new Article();
  18. article.setId(1);
  19. article.setTitle("震惊了,ES竟然可以这么用");
  20. article.setAuthor("UC编辑部");
  21. article.setContent("********震惊了,ES竟然可以这么用*********");
  22. articleRepository.save(article);
  23. }
  24. @Test
  25. public void test2(){
  26. Optional<Article> optional = articleRepository.findById(1);
  27. optional.ifPresent(article->{
  28. System.out.println("article = " + article);
  29. });
  30. }
  31. }