目录

springboot与检索

检索

官方文档

我们的应用经常需要添加检索功能,开源的 是目前全文搜索引擎的 首选。他可以快速的存储、搜索和分析海量数据。Spring Boot通过整合Spring Data ElasticSearch为我们提供了非常便捷的检索功能支持;

Elasticsearch是一个分布式搜索服务,提供Restful API,底层基于Lucene,采用 多shard(分片)的方式保证数据安全,并且提供自动resharding的功能,github 等大型的站点也是采用了ElasticSearch作为其搜索服务,

概念

以 员工文档 的形式存储为例:一个文档代表一个员工数据。存储数据到 ElasticSearch 的行为叫做 索引 ,但在索引一个文档之前,需要确定将文档存 储在哪里。

一个 ElasticSearch 集群可以 包含多个 索引 ,相应的每个索引可以包含多 个 类型 。 这些不同的类型存储着多个 文档 ,每个文档又有 多个 属性 。

http://img.cana.space/picStore/20201026210939.png

类似关系:

  • 索引-数据库
  • 类型-表
  • 文档-表中的记录
  • 属性-列

整合ElasticSearch测试

安装es

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 下载镜像
由于这里我使用的是springboot2.3.x对应的es版本是7.6.2,所以下载7.6.2版本
版本说明:https://github.com/spring-projects/spring-data-elasticsearch/blob/master/src/main/asciidoc/preface.adoc
$ docker pull elasticsearch:7.6.2
# 启动镜像
$ docker run --name es7.6.2 -p 9200:9200 -p 9300:9300 \
-e ES_JAVA_OPTS="-Xms512m -Xmx512m" \
-e "discovery.type=single-node" \
-d elasticsearch:7.6.2
# 参数说明
--name elasticsearch:将容器命名为 es7.6.2
-p 9200:9200:将容器的9200端口映射到宿主机9200端口,目的是web通信
-p 9300:9300:将容器的9300端口映射到宿主机9300端口,目的是集群互相通信
-e ES_JAVA_OPTS="Xms512m -Xmx512m":配置内存大小,es默认内存大小2G
-e "discovery.type=single-node" 单节点集群
# 查看容器日志
$ docker logs -f 78
# 访问es
http://localhost:9200/
{
  "name" : "78c5730456eb",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "YGygyMjfSiajubUYFOPKLQ",
  "version" : {
    "number" : "7.6.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
    "build_date" : "2020-03-26T06:34:37.794943Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

演示ES使用

索引文档

参考:索引文档

http://img.cana.space/picStore/20201026212745.png

检索文档

参考: 取回一个文档

http://img.cana.space/picStore/20201026213030.png

技巧
ES将HTTP命令由PUT改为GET可以用来检索文档,同样的,可以使用DELETE命令来删除文档,以及使用HEAD指令来检查文档是否存在(200存在404不存在)。如果想更新已存在的文档,只需再次PUT。

springboot整合es

完整示例地址

  1. 引入spring-boot-starter-data-elasticsearch

  2. application.yml配置,这里偷懒取默认配置即可

  3. Spring Boot自动配置的 ElasticsearchRepository、ElasticsearchTemplate

  4. 测试使用ElasticsearchRepository来处理数据

    1. 定义实体类

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      
      package com.eh.springbootelasticsearch.bean;
            
      import lombok.AllArgsConstructor;
      import lombok.Data;
      import lombok.NoArgsConstructor;
      import org.springframework.data.annotation.Id;
      import org.springframework.data.elasticsearch.annotations.Document;
            
      @Document(indexName = "eh", shards = 5)
      @Data
      @AllArgsConstructor
      @NoArgsConstructor
      public class Book {
          @Id
          private Integer id;
          private String name;
          private String author;
      }
      
    2. spring-data-es也遵从jpa规范

      定义BookRepository类继承ElasticsearchRepository

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      
      package com.eh.springbootelasticsearch.bean;
            
      import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
            
      import java.util.List;
            
      public interface BookRepository extends ElasticsearchRepository<Book, Integer> {
          /**
           * spring-data-es遵从jpa规范,直接编写符合规定的方法名即可
           * 这里会根据名称进行匹配查找
           * 更多规范请参考:https://docs.spring.io/spring-data/elasticsearch/docs/4.0.4.RELEASE/reference/html/
           * @param bookName
           * @return
           */
          List<Book> findByNameLike(String bookName);
      }
      
    3. 编写测试类保存数据

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      
      package com.eh.springbootelasticsearch;
            
      import com.eh.springbootelasticsearch.bean.Book;
      import com.eh.springbootelasticsearch.bean.BookRepository;
      import org.junit.jupiter.api.Test;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.boot.test.context.SpringBootTest;
            
      @SpringBootTest
      class SpringbootElasticsearchApplicationTests {
            
          @Autowired
          private BookRepository bookRepository;
            
          @Test
          void contextLoads() {
              Book book = new Book(1, "三国演义", "罗贯中");
              bookRepository.save(book);
          }
            
          /**
           * 运行结果:Book(id=1, name=三国演义, author=罗贯中)
           */
          @Test
          void test1() {
              Book book = bookRepository.findByNameLike("国").get(0);
              System.out.println(book);
          }
      }
      
    4. 访问book

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      
      GET http://localhost:9200/eh/_search
            
      HTTP/1.1 200 OK
      content-type: application/json; charset=UTF-8
            
      {
        "took": 8,
        "timed_out": false,
        "_shards": {
          "total": 5,
          "successful": 5,
          "skipped": 0,
          "failed": 0
        },
        "hits": {
          "total": {
            "value": 1,
            "relation": "eq"
          },
          "max_score": 1.0,
          "hits": [
            {
              "_index": "eh",
              "_type": "_doc",
              "_id": "1",
              "_score": 1.0,
              "_source": {
                "_class": "com.eh.springbootelasticsearch.bean.Book",
                "id": 1,
                "name": "三国演义",
                "author": "罗贯中"
              }
            }
          ]
        }
      }
            
      Response code: 200 (OK); Time: 101ms; Content length: 312 bytes