ES的简单使用 SpringBoot整合ES(Jest, spring-data-elasticsearch)

检索功能

  • 简介
  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对象

springboot筛选 springboot 搜索功能_搜索

  1. 简单操作
  • 存储雇员数据, 以雇员文档的形式存储, 存储数据到ES的行为叫做索引. 但在索引一个文档之前, 需要确定将文档存储到哪.
  • ES集群中可以有多个索引, 每个索引可包含多个类型, 每个类型可包含多个文档, 而每个文档之间又可以有多个属性.

springboot筛选 springboot 搜索功能_springboot筛选_02

  • 对于雇员目录, 做如下操作
  • 每个雇员索引一个文档, 包含该雇员的所有信息.
  • 每个文档都是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

springboot筛选 springboot 搜索功能_springboot筛选_03

  • 同理, 发DELETE请求是删除, 发HEAD请求来检查是不是有这个员工
  • 若要更新已存在的文档, 只需再次PUT.
  • 这里的版本会叠加, 同时result : "updated"
  1. 搜索功能
  • 查询所有员工
GET /megacorp/employee/_search
  • 按条件查找
GET /megacorp/employee/_search?q=last_name:Smith
  • 查询表达式

springboot筛选 springboot 搜索功能_elasticsearch_04

  • 全文检索
  • 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/
  1. 测试
  • 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
  1. 配置
spring.data.elasticsearch.cluster-name=docker-cluster
spring.data.elasticsearch.cluster-nodes=192.168.13.129:9300
  1. 用法
  • 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("游");
    }