springboot10-检索

检索功能

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

    docker run -d -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" --name es01 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" 镜像ID

  • 简单使用
  1. ES是面向文档的, 意味着它存储整个对象或文档, 同时, 索引每个文档的内容使之可以被检索.
  2. 在ES中, 使用JSON作为文档的序列化格式.
    • 如一个User对象
  3. 简单操作
    • 存储雇员数据, 以雇员文档的形式存储, 存储数据到ES的行为叫做索引. 但在索引一个文档之前, 需要确定将文档存储到哪.
      • ES集群中可以有多个索引, 每个索引可包含多个类型, 每个类型可包含多个文档, 而每个文档之间又可以有多个属性.
    • 对于雇员目录, 做如下操作
      • 每个雇员索引一个文档, 包含该雇员的所有信息.
      • 每个文档都是employee类型
      • 该类型位于索引megacors内.
      • 该索引保存在我们的ES集群中
        PUT /megacorp/employee/1
        {
            "first_name" : "john",
            "last_name" : "Smith",
            "age" : 25,
            "about" : "I love to go rock climbing",
            "interests" : ["sports", "music"]    
        }
        
        megacorp是索引名称
        employee是类型名称
        1代表特定雇员的ID
    • 检索时只需发GET /megacorp/employee/1
    • 同理, 发DELETE请求是删除, 发HEAD请求来检查是不是有这个员工
    • 若要更新已存在的文档, 只需再次PUT.
      • 这里的版本会叠加, 同时result : "updated"
  4. 搜索功能
    • 查询所有员工
      GET /megacorp/employee/_search
    • 按条件查找
      GET /megacorp/employee/_search?q=last_name:Smith
    • 查询表达式
    • 全文检索
      • ES中的检索并非像传统数据库那样内容必须严格一致才能搜出来, 而有一个字段叫相关性得分, 得分越高, 则字段越相近.
    • 短语搜索(严格匹配)
      • 需用到"match_phrase"
        {
            "query" : {
                "match_phrase" : {
                    "about" : "rock climbing"
                }
            }
        }
    • 高亮搜索
      {
          "query" : {
              "match_phrase" : {
                  "about" : "rock climbing"
              }
          },
          "highlight" : {
              "fields" : {
                  "about" : {}
              }
          }
      }

SpringBoot整合ElasticSearch

  • 依赖
  1. 导入依赖
  2. SpringBoot默认支持两种技术与ES交互
    <!--SpringBoot默认使用SpringData ElasticSearch模块进行操作-->
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
    或者
    <dependency>
        <groupId>io.searchbox</groupId>
        <artifactId>jest</artifactId>
        <version>6.3.1</version>
    </dependency>
    • Jest
      • 不导入第二个依赖不会生效.
    • SpringData ElasticSearch 
      • Client 节点信息(clusterNodes, clusterName)
      • ElasticsearchTemplate 操作ES
      • 编写一个ElasticsearchRepository的子接口来操作ES
  • 使用Jest操作ES
  1. 配置: application.properties
    spring.elasticsearch.jest.uris=http://192.168.13.129:9200/
  2. 测试
    • bean信息
      public class Article {
      
          @JestId //主键
          private Integer id;
          private String auth;
          private String title;
          private String content;
      
          //...
      }
    • 测试
          @Autowired
          private JestClient jestClient;
      
          //测试添加
          @Test
          public void contextLoads() {
              //1. 给ES中索引一个文档
              Article article = new Article();
              article.setId(1);
              article.setTitle("好消息");
              article.setAuth("zhangsan");
              article.setContent("Hello world");
      
              //构建一个索引功能
              Index index = new Index.Builder(article).index("yellowstreak").type("news").build();
      
              try {
                  //执行
                  jestClient.execute(index);
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      
          //测试搜索
          @Test
          public void search() {
              //查询表达式
              String json = "{\n" +
                      "\t\"query\" : {\n" +
                      "\t\t\"match\" : {\n" +
                      "\t\t\t\"content\" : \"hello\"\n" +
                      "\t\t}\n" +
                      "\t}\n" +
                      "}";
      
              //构建搜索功能
              Search search = new Search.Builder(json).addIndex("yellowstreak").addType("news").build();
      
              //执行
              try {
                  SearchResult result = jestClient.execute(search);
                  System.out.println(result.getJsonString());
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
  • 整合SpringData ES模块
  1. 注意: 目前spring-data-elasticsearch支持6.x版本, 不支持7.x版本.
    • 版本不匹配会报错
      NoNodeAvailableException None of the configured nodes are available
  2. 配置
    spring.data.elasticsearch.cluster-name=docker-cluster
    spring.data.elasticsearch.cluster-nodes=192.168.13.129:9300
  3. 用法
    • bean
      @Document(indexName = "yellowstreak", type = "book")
      public class Book {
      
          private Integer id;
          private String bookName;
          private String author;
      
          //...
      }
    • 编写一个ElasticsearchRepository的子接口
      public interface BookRepository extends ElasticsearchRepository<Book, Integer> {
      
          //自定义命名方法名
          public List<Book> finByBookNameLike(String bookName);
      
    • 测试
          @Autowired
          private BookRepository bookRepository;
      
          @Test
          public void test02() {
              Book book = new Book();
              book.setId(1);
              book.setBookName("西游记");
              book.setAuthor("吴承恩");
              bookRepository.index(book);
      
              List<Book> books = bookRepository.finByBookNameLike("游");
          }
posted @ 2020-06-17 16:18  yellowstreak  阅读(170)  评论(0编辑  收藏  举报