35 Spring整合Elasticsearch

Spring整合Elasticsearch

引入依赖

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

配置Elasticsearch

  • cluster-name集群名
  • cluster-nodes集群节点
# ElasticsearchProperties
# 配置集群名,与es配置文件中的一致
spring.data.elasticsearch.cluster-name=nowcoder
# 集群节点,格式  节点ip地址:端口
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300

解决冲突

如果项目中使用了redis,则需要解决冲突

es和redis都基于netty,这两者在启动netty时,会产生冲突:系统会认为redis已经启动了netty,es无法再启动

要尽可能在服务启动早期的时候,修改es.set.netty.runtime.available.processors为 false

修改入口类,因为入口类是最先被加载的

@PostConstruct: 管理bean的生命周期,主要用于初始化的方法,该注解修饰的方法在构造器调用完以后被执行

在这个初始化方法中修改系统属性就足够早

@SpringBootApplication
public class CommunityApplication {
   
    
    
	
    @PostConstruct
    public void init() {
   
    
    
        // 解决netty启动冲突问题
        // es.set.netty.runtime.available.processors 从 Netty4Utils.setAvailableProcessors() 中找到
        // 设置系统属性
        System.setProperty("es.set.netty.runtime.available.processors", "false");
    }

    public static void main(String[] args) {
   
    
    
        SpringApplication.run(CommunityApplication.class, args);
    }

}

使用Elasticsearch

Spring Data Elasticsearch

用于访问es服务器的API

  • ElasticsearchTemplate :有特殊情况,DiscussPostRepository处理不了时使用

  • ElasticsearchRepository: 接口,需要定义一个子接口继承他,声明访问哪些数据,Spring会自动实现这个接口

    所有的代码都是Spring自动生成的,Spring会自动将实体数据和es服务器的索引进行映射,因此需要用注解

    代码实例:

    // es可以看成特殊的数据库,因此加上注解@Repository
    // @Mapper是MyBa'ti'd专有注解
    // @Repository是spring提供的,针对数据访问层的注解
    @Repository
    // es的接口一般取名XXXRepository,该接口访问的是帖子,故叫DiscussPostRepository
    public interface DiscussPostRepository extends ElasticsearchRepository<DiscussPost, Integer> {
         
          
          
        // 继承时要用泛型声明:当前接口要处理的实体类,以及实体类中的id类型
    
        // 父接口ElasticsearchRepository中 已经定义好了对es服务器访问的增删改查方法
        // 声明完泛型,加上注解之后,spring会自动实现自定义的子接口DiscussPostRepository
    }
    

建立映射关系

要对spring说明哪个实体类和es的索引怎样进行对应,建立映射关系,映射完成后,spring底层就可以帮我们生成实现类

  1. 用@Document指明 表 和 es 中索引的对应关系

    @Document ( indexName = “…”, type = “…”, shards = , replicas = )

    indexName: 实体数据映射到哪个索引上。通常为全小写的类名
    type: 实体数据映射到哪个类型上。类型已经在逐步被弱化甚至取消了,因此写成固定的 _doc
    shards: 创建几个分片。根据服务器处理能力配
    replicas: 创建几个副本。
    没有指定索引会创建这个索引,并且是根据指定分片和副本进行创建的

  2. 指明 实体中属性 和 es中字段 的对应关系

    给类中每个 属性 上加注解用于和 索引中的字段 相关联

​ 表的id属性要 加 @id 注解

    @Id // 与索引中id字段对应
    private int id;

​ 其他普通属性 加 @Field注解并指明字段类型

    // 用于普通字段,需指明字段类型
    @Field(type = FieldType.Integer)
    private int userId;

​ 当某些属性 对应的 es字段要用于关键词匹配时,需在注解中指明使用的analyzer和searchAnalyzer

​ analyzer为存储时候的解析器/分词器。

当我们存一句话时,会提取出关键词,并用关键词关联这句话,搜索时就可以通过关键词搜到这句话
因此存的时候,因该尽可能将一句话拆出尽可能多的关键词,以扩大搜索范围。
故需要一个范围非常大的分词器,而我们安装的中文分词器中存在这样的分词器——ik_max_word

​ searchAnalyzer为搜索时候解析器/分词器

搜索时,输入的句子不需要拆出过多关键词,不用拆的过细
如”互联网校招“,可以拆出:互联网、联网、网校、校招等关键词,但实际上我们没有这些意思
此时要使用拆分出尽可能少但满足用户需求的词语——ik_smart

    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private String content;
// 将数据库中帖子存到es服务器里,就可以去es服务器中搜索这些帖子了
@Document(indexName = "discusspost", type = "_doc", shards = 6, replicas = 3)
public class DiscussPost {
   
    
    

    @Id // 与索引中id字段对应
    private int id;

    // userId为普通字段
    @Field(type = FieldType.Integer)
    private int userId;

    // 搜帖子主要在title和content中查找
    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private String title;

    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private String content;

    // 不用在这些字段进行搜索,就不用analyzer和searchAnalyzer属性
    @Field(type = FieldType.Integer)
    private int type;

    

猜你喜欢

转载自blog.csdn.net/ShirleyZ1007/article/details/136428178
35