从零搭建Spring Boot脚手架(7):Elasticsearch应该独立服务

1. Spring Data Elasticsearch

Spring Data ElasticsearchSpring Data项目的子项目,提供了ElasticsearchSpring的集成。实现了Spring Data Repository风格的Elasticsearch文档交互风格,让你轻松进行Elasticsearch客户端开发。html

2. 我的的一些见解

应粉丝要求特意将Elasticsearch整合到Spring Boot 中去。原本打算整合到kono脚手架中,可是转念一想这样并非很是合适,通常搜索建议做为一个独立的平台运做,小公司可做为一个独立的服务,大公司可做为一个搜索中台。通常我认为虽然Elasticsearch提供了搜索功能,大部分状况下咱们并不像常规的关系型数据库同样进行直接写入,而是经过同步的方式进行同步或者预热写入数据。java

数据经过Logstash同步到ES

具体的架构不是本文要讲的,在ES的CSDN官方博客里面有比较具体的解决方案。本文是在你已经搭建好Elasticsearch集群的前提下进行的。react

2. 版本对应

相关项目的版本对应关系以下:spring

Spring Data Release Train Spring Data Elasticsearch Elasticsearch Spring Boot
Neumann 4.0.x 7.6.2 2.3.x
Moore 3.2.x 6.8.6 2.2.x
Lovelace 3.1.x 6.2.2 2.1.x
Kay 3.0.x 5.5.0 2.0.x
Ingalls 2.1.x 2.4.0 1.5.x

根据我日常的作法,我选择Elasticsearch 7.6.2Spring Boot 2.3.3做为版本基准进行集成。数据库

3. 依赖引入及配置

只须要引入下面的依赖就能够集成Elasticsearch :json

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

关于配置有两种一种面向传统的Restful:架构

spring:
  elasticsearch:
    rest:
      # 逗号分隔的Elasticsearch实例使用的列表 
      uris: http://localhost:9200
      # 连接超时时间
      connection-timeout:
      # 读取超时时间
      read-timeout:
      # ES 用户名
      username:
      # ES 密码
      password:
若是你都采用默认的配置,能够什么都不配置,包括 uris

另外一种面向反应式:框架

spring:  
  data:
    elasticsearch:
      client:
        #  反应式相关的配置
        reactive:
        #  端点       
          endpoints:
          connection-timeout:
          max-in-memory-size:
          socket-timeout:
          use-ssl:
          username:
          password:

这里配合的是Spring Webflux反应式框架,我我的其实更加倾向于此,可是做为目前的主流仍是选择了第一种。socket

务必保证 spring.data.elasticsearch.repositories.enabled = true,不然没法使用 Spring Data Repository模式。

4. 操做

这里演示面向传统的Restful,一共有两种风格。假如咱们向写入了Blogelasticsearch

{
  "blogId": "132435553",
  "blogTitle": "脚手架集成elasticsearch",
  "author": "felord",
  "content": "全称为Object Storage Service,也叫对象存储服务,是一种解决和处理离散单元的方法,可提供基于分布式系统之上的对象形式的数据存储服务,具备可拓展、可管理、低成本等特色,支持中心和边缘存储,可以实现存储需求的弹性伸缩,主要应用于海量数据管理的各种场景。\n\n这概念真是够难以理解的。简单说点我知道的吧,日常咱们的文件地址都是 /User/felord/video/xxx.mp4的目录树结构,系统先要找到User,而后一级一级往下找一直到目标为止,这是一种结构化的存储方式。对象存储就不同了,全部的文件都放在一个特定的池子里,只不过文件的携带有它本身的元信息,经过元信息去检索文件。",
  "url": "https://felord.cn/my-spring-boot-day7.html",
  "publishedTime": "2020-08-30T22:17:40"
}

对应的POJO对象为:

/**
 * @author felord.cn
 * @since 2020/8/30 16:10
 */
@Document(indexName = "blogs")
@Data
public class Blog {
    @Id
    private String blogId;
    private String blogTitle;
    private String author;
    private String content;
    private String url;
    @Field(type = FieldType.Date,format = DateFormat.date_hour_minute_second)
    private LocalDateTime publishedTime;
}
  • @Document用来标记文档对象,包含了该文档的一些元信息,索引副本数,分片数。
  • @Id 文档的标识符。
  • @Field 文档字段的一些元信息配置,类型、名称、分词器等等。

主要有以上三种,还有其它的一些注解标记,这里再也不讲述。

4.1 ElasticsearchRestTemplate

RedisTemplate相信你已经不陌生了,一样的,Spring Data Elasticsearch提供了ElasticsearchRestTemplate来操做Elasticsearch,增删改查应有尽有。这里演示进行复杂的Criteria查询。

从blogs索引中查询blogId为132435553并且包含elastic词汇的标题的文档,同时查询词汇高亮

@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Test
void testTemplate() {

    // 构造条件  
    Criteria criteria = Criteria.where(new SimpleField("blogId"))
            .is("132435553")
            .and(new SimpleField("blogTitle"))
            .contains("elastic");

    CriteriaQuery criteriaQuery = new CriteriaQuery(criteria);
    // 高亮
    HighlightBuilder blogTitle = SearchSourceBuilder.highlight().field("blogTitle");
    HighlightQuery highlightQuery = new HighlightQuery(blogTitle);
    criteriaQuery.setHighlightQuery(highlightQuery);
    SearchHits<Blog> blogSearchHits = elasticsearchRestTemplate.search(criteriaQuery, Blog.class);
    blogSearchHits.getSearchHits().forEach(System.out::println);
}

4.2 Spring Data Repository

Spring Data Repository的核心接口是Repository。这个接口须要领域类(好比上面的Blog)跟领域类的ID类型做为参数。这个接口主要是让你能知道继承这个类的接口的类型。CrudRepository提供了对被管理的实体类的一些经常使用增删改查方法。那么针对Elasticsearch提供了各类特点的接口:

Elasticsearch Repository 接口家族

Repository模式提供了一种利用方法名称进行条件构造的查询方式。

IDEA 提供了智能提示来帮助咱们构造方法条件

这种方式好处就是语义化,坏处就是方法名称可能很是的长。对于4.1中的例子咱们能够简化为:

/**
 * @author felord.cn
 * @since 2020/8/30 21:32
 */
public interface BlogRepository extends ElasticsearchRepository<Blog,String> {



    @Highlight(fields = {
            @HighlightField(name = "blogTitle")
    })
    List<SearchHit<Blog>> searchBlogByBlogIdAndBlogTitleContains(String blogId, String titleContains);


}

另外一种是采用注解方式,使用@Query注解,好比咱们根据blogId进行查询咱们能够这么写:

@Query("{\"match\": {\"blogId\": \"?0\" }}")
//    @Query("{\"match\": {\"blogId\":{\"query\": \"?0\"}}}")
    Blog searchById(String blogId);

这个优势就是更加灵活,并且写法也更加随意简单;缺点就是须要熟悉Spring Data Elasticsearch以及Elasticsearch的查询语法,有必定的学习成本。

总结

以上就是简单的Spring Data Elasticsearch入门,对于使用Elasticsearch的项目来讲,通常都具备了很大的数据量,因此要根据业务的须要进行具体的设计,Spring Data Elasticsearch能让咱们很是方便进行搜索操做,若是你在使用中遇到什么问题能够经过公众号:码农小胖哥留言进行讨论。

关注公众号:Felordcn 获取更多资讯

我的博客:https://felord.cn

相关文章
相关标签/搜索