最简单的Spring Boot集成elasticsearch 6.2.2

Posted 贝塔-突突

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最简单的Spring Boot集成elasticsearch 6.2.2相关的知识,希望对你有一定的参考价值。

前言(介绍)

Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。搜索引擎框架中不止Elasticsearch 框架,例如Lucene,Solandra,Solr,Compass等很多,举例,Lucene是将数据存在本地,生成一个个文件等,在说说为什么使用 Elasticsearch 分布式搜索引擎,因为方便,有很多可视化工具,例如 Kibana , Elasticsearch - head 还有 ik分词,总体来说方便管理,官方:

  1. 分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索。
  2. 实时分析的分布式搜索引擎。
  3. 可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据

下载地址:

  1. Kibana: https://www.elastic.co/cn/downloads/past-releases/kibana-6-2-2
  2. Elasticsearch https://www.elastic.co/cn/downloads/past-releases#elasticsearch
  3. Elasticsearch-head: https://github.com/mobz/elasticsearch-head
  4. ik分词:https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v6.2.2

简介(吹水)

不知道有没有遇到一些领导是这样的,在一天早上,领导看到自己在公司像逛gai,然后就给我安排任务,然后过后跟我说推个锅给我,前期我拒绝的,然后就一句已经禅道推给你了(欲哭无泪,因为没学过),说要做个搜索,不要用 SQL LIKE,叫我问带我的领导怎么弄,然后问带我们的大佬,大佬说太久没弄了,让我自己研究,然后一直躺坑的过来了,真的是一直躺坑,有点怀疑人生了,想放弃了,不过最后还是做好了。

坑点:

  1. 版本一定要对应,比如,elasticsearch 6.2.2,kibana 6.2.2,Elasticsearch - head 6.2.2 ,elasticsearch-analysis-ik 6.2.2
  2. 要分清楚什么是用 ElasticsearchRepository,什么时候用RestHighLevelClient,刚刚开始学的时候就很乱对这些。
  3. 有spring-boot-starter-data-redis 依赖会报错,网上好像说是netty版本不一致问题

很多人可能会想,为什么还用这么老的版本,说实话我也不想,最开始看b站狂神的 Elasticsearch , 查数据的时候会导致有些数据查不到,而且版本不适用,因为我们的项目没有父工程,无法覆盖版本,公司是Spring Boot 2.2.1 版本,做了很多模块,自己一改,项目直接崩溃,只好找对应版本

一、最简单的整合

pom.xml

前提是没有spring-boot-starter-data-redis

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>6.2.2</version>
        </dependency>

yml

spring:
   data:
     elasticsearch:
      repositories:
        enabled: true
      cluster-nodes: 127.0.0.1:9300

UserRepository

/**
 * @Author: Lanys
 * @Description:
 * @Date: Create in 23:24 2021/7/28
 */
@Repository
public interface UserRepository extends ElasticsearchRepository<User, Integer> {
}

User

/**
 * @Author: Lanys
 * @Description:
 * @Date: Create in 23:30 2021/7/28
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(indexName = "my_user")
public class User {
    /**
     *     index:是否设置分词
     *     analyzer:存储时使用的分词器
     *     searchAnalyze:搜索时使用的分词器
     *     store:是否存储
     *     type: 数据类型
     */
    @Id
    @Field(store = true, index = false, type = FieldType.Integer)
    private Integer id;
    @Field(type = FieldType.Text, store = true, analyzer = "ik_smart")
    private String username;
    @Field(store = true, type = FieldType.Keyword, analyzer = "my_user", searchAnalyzer = "my_user")
    private String password;
    @Field(store = true, type = FieldType.Integer, analyzer = "my_user", searchAnalyzer = "my_user")
    private Integer age;
}
// 插入数据
        @Test
        public void testInsert(){
            userRepository.save(new User(3, "迪迦", "123", 18));
            userRepository.save(new User(4, "盖亚", "321", 18));
            userRepository.save(new User(6, "雷欧", "123", 18));
            userRepository.save(new User(7, "戴罗", "321", 18));
            userRepository.save(new User(8, "爱思", "yao3210", 18));
            userRepository.save(new User(9, "杰克", "312", 18));
            userRepository.save(new User(10, "高斯", "321", 18));
            userRepository.save(new User(11, "赛文", "3134", 18));
            userRepository.save(new User(12, "贝利亚", "32423", 18));
            userRepository.save(new User(13, "艾伦", "321", 18));
            userRepository.save(new User(137, "泰罗", "3213", 18));
        }
@Test
    public void s5(){
        // 构建查询条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 添加基本分词查询 ik分词
        queryBuilder.withQuery(QueryBuilders.matchQuery("username", "大学西北林新明邓紫"));
        // 搜索,获取结果
        Page<User> items = userRepository.search(queryBuilder.build());
        // 总条数
        long total = items.getTotalElements();
        System.out.println("total = " + total);
        items.forEach(item -> System.out.println("item = " + item));

    }


二、Spring Boot集成elasticsearch 6.2.2

pom.xml

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>6.2.2</version>
        </dependency>

application.yml

spring:
   data:
     elasticsearch:
      repositories:
        enabled: true
      cluster-nodes: 127.0.0.1:9300

ElasticsearchConfig

解决 spring-boot-starter-data-redis 依赖会报错

/**
 * @author lanys
 * @Description:
 * @date 27/7/2021 下午3:33
 */
@Configuration
//指定RedisConfig文件
@AutoConfigureBefore(RedisConfig.class)
@EnableCaching
public class ElasticsearchConfig {

    @PostConstruct
    void init() {
        System.setProperty("es.set.netty.runtime.available.processors", "false");
    }

    @Bean(name = "elasticsearchTemplate")
    public ElasticsearchTemplate elasticsearchTemplate(Client client,
                                                       ElasticsearchConverter converter) {
        try {
            return new ElasticsearchTemplate(client, converter);
        }
        catch (Exception ex) {
            throw new IllegalStateException(ex);
        }
    }

    @Bean
    public ElasticsearchConverter elasticsearchConverter(
            SimpleElasticsearchMappingContext mappingContext) {
        return new MappingElasticsearchConverter(mappingContext);
    }

    @Bean
    public SimpleElasticsearchMappingContext mappingContext() {
        return new SimpleElasticsearchMappingContext();
    }

}

ElasticsearchIndexName

/**
 * @author lanys
 * @Description: Elasticsearch 索引名称
 * @date 28/7/2021 下午2:11
 */
public class ElasticsearchIndexName {

    /**
     * 动态索引
     */
    public final static String DYNAMIC_SEARCH = "dynamic";

    /**
     * 动态搜索字段
     */
    public final static String DYNAMIC_CONTENT = "content";


    /**
     * 用户索引
     */
    public final static String USER_SEARCH = "user";

    /**
     * 用户搜索字段
     */
    public final static String USER_CONTENT = "nickname";
}

UserSearchEsVo

/**
 * @author lanys
 * @Description: ES 用户表搜索
 * @date 29/7/2021 下午4:12
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName = ElasticsearchIndexName.USER_SEARCH)
public class UserSearchEsVo implements Serializable {

    /**
     *用户ID
     */
    @Id
    private Long id;

    /**
     *昵称
     */
    @Field(store = true,  type = FieldType.Keyword, analyzer = "ik_max_word", searchAnalyzer = "ik_max_word")
    private String nickname;

    /**
     *头像URL
     */
    private String avatar;

    /**
     *个性签名/内心独白
     */
    private String sign;

    /**
     *城市
     */
    private String city;

    /**
     *登录用户是否关注发布者
     */
    private Integer isFollow;

}

UserSearch

/**
 * @author lanys
 * @Description:
 * @date 30/7/2021 下午5:49
 */
@Component
public interface UserSearch extends ElasticsearchRepository<UserSearchEsVo,Long> {
}

IEsSearchService

/**
     * ES 用户搜索
     * @param userId
     * @param message
     * @param page
     * @param num
     * @return
     */
    List<UserSearchEsVo> userSearch(Long userId, String message, Integer page, Integer num);

    /**
     * 添加用户数据到es中
     * @return
     */
    Boolean addUserSearchData();

EsSearchServiceImpl

@Slf4j
@Service
public class EsSearchServiceImpl implements IEsSearchService {


    @Autowired
    private UserSearch userSearch;

 /**
     * 用户搜索
     *
     * @param userId
     * @param page
     * @param num
     * @return
     */
    @Override
    public List<UserSearchEsVo> userSearch(Long userId, String message, Integer page, Integer num) {
//        Page<UserSearchEsVo> search = userSearch.search(publicSearchBasics(ElasticsearchIndexName.USER_SEARCH,message,page,num).build());
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        
       //模糊查询        
       nativeSearchQueryBuilder.withQuery(QueryBuilders.matchQuery(ElasticsearchIndexName.USER_CONTENT, message));
        //查询
        Page<UserSearchEsVo> search = userSearch.search(nativeSearchQueryBuilder.build());
        List<UserSearchEsVo> UserSearchEsVoList = search.getContent();
      
        return UserSearchEsVoList;
    }

    @Override
    public Boolean addUserSearchData() {
        //根据自己的数据自己添加
        List<UserSearchEsVo> user2Es = userMapper.getUser2Es();
        try{
            userSearch.saveAll(user2Es);
        }catch (Exception e){
            log.error("数据异常",e);
            return false;
        }
        return true;
    }
}



如果是高版本的话,差别也不是很大,我还整合了7.6.0版本的,用法有点不一样,如果需要就整上还有配置,好了结束。

以上是关于最简单的Spring Boot集成elasticsearch 6.2.2的主要内容,如果未能解决你的问题,请参考以下文章

如何在与MongoDB集成的Spring boot Elastic Search中实现对非结构化数据的搜索

最简单的Spring Boot集成elasticsearch 6.2.2

Elastic Search 浅浅认识 快速使用 keyword 和 text 的区别之处 spring boot 集成案例 es 增删改查

ElasticSearch 副本-04Spring Boot 集成 ElasticSearch

AWS Elastic Beanstalk 上的 Spring Boot 并记录到文件

Spring Boot 不适用于 Elastic Beanstalk