SpringBoot整合Elasticsearch配置与使用

Spring整合ES步骤

  • 引入依赖
  • 配置Elasticsearch
    • cluster-name
    • cluster-nodes
  • Spring Data Elasticsearch
    • ElasticsearchTemplate
    • ElasticsearchRepository

导包

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

配置 ElasticsearchProperties

# ElasticsearchProperties
spring.data.elasticsearch.cluster-name=wsc
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300 #9300tcp端口 9200 http端口

解决与redis的netty冲突

NettyRuntime类的

Netty4Utils.setAvailableProcessors()

在springboot启动类中添加下面这段代码解决与redis的netty冲突

@SpringBootApplication
public class CommunityApplication {

    @PostConstruct
    public void init() {
        // 解决netty启动冲突问题
        // see Netty4Utils.setAvailableProcessors()
        System.setProperty("es.set.netty.runtime.available.processors", "false");
    }

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

}

将数据库的帖子存入Elasticsearch

通过注解实体数据与es索引进行映射,主要进行搜索的content和title上配置尤为重要

存储的时候使用 ik_max_word分词器尽可能拆出更多的单词

搜索的时候使用ik_smart分词器,没有必要拆出很多单词
SpringBoot整合Elasticsearch配置与使用_第1张图片

定义访问接口

@Repository
public interface DiscussPostRepository extends ElasticsearchRepository<DiscussPost,Integer> {
    
}

往es中存数据(帖子)

 @Test
    public void testInsert(){
        discussRepository.save(discussMapper.selectDiscussPostById(241));
        discussRepository.save(discussMapper.selectDiscussPostById(242));
        discussRepository.save(discussMapper.selectDiscussPostById(243));
    }

在这里插入图片描述

用postman查询刚刚存进去的数据

SpringBoot整合Elasticsearch配置与使用_第2张图片

SpringBoot整合Elasticsearch配置与使用_第3张图片

saveall同时向es中插入多条数据

//插入多条数据
    @Test
    public void testInsertList(){
        discussRepository.saveAll(discussMapper.selectDiscussPost(101,0,100));
        discussRepository.saveAll(discussMapper.selectDiscussPost(102,0,100));
        discussRepository.saveAll(discussMapper.selectDiscussPost(103,0,100));
        discussRepository.saveAll(discussMapper.selectDiscussPost(111,0,100));
        discussRepository.saveAll(discussMapper.selectDiscussPost(112,0,100));
        discussRepository.saveAll(discussMapper.selectDiscussPost(131,0,100));
        discussRepository.saveAll(discussMapper.selectDiscussPost(132,0,100));
        discussRepository.saveAll(discussMapper.selectDiscussPost(133,0,100));
        discussRepository.saveAll(discussMapper.selectDiscussPost(134,0,100));
    }

SpringBoot整合Elasticsearch配置与使用_第4张图片SpringBoot整合Elasticsearch配置与使用_第5张图片

测试数据的删除

 //测试数据的删除
    @Test
    public void testDelete(){
        discussRepository.delete(discussMapper.selectDiscussPostById(231));
    }

实现搜索

四个关键点构造查询条件

  • 搜索关键词 QueryBuilders
  • 分页方式PageRequest
  • 排序SortBuilders
  • 高亮搜索 HighlightBuilder

elasticTemplate.queryForPage(searchQuery, class, SearchResultMapper)
底层获取得到了高亮显示的值, 但是没有返回.

@Test
    public void testSearchByRepository() {
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content")) //搜索条件
                .withSort(SortBuilders.fieldSort("type").order(SortOrder.DESC))//排序条件
                .withSort(SortBuilders.fieldSort("score").order(SortOrder.DESC))
                .withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))
                .withPageable(PageRequest.of(0, 10)) //分页条件
                .withHighlightFields(
                        new HighlightBuilder.Field("title").preTags("").postTags(""),//高亮显示
                        new HighlightBuilder.Field("content").preTags("").postTags("")
                ).build();

        // elasticTemplate.queryForPage(searchQuery, class, SearchResultMapper)
        // 底层获取得到了高亮显示的值, 但是没有返回.

        Page<DiscussPost> page = discussRepository.search(searchQuery);
        System.out.println(page.getTotalElements());
        System.out.println(page.getTotalPages());
        System.out.println(page.getNumber());
        System.out.println(page.getSize());
        for (DiscussPost post : page) {
            System.out.println(post);
        }
    }

使用elasticTemplate替代discussRepository实现高亮搜索

Page<DiscussPost> page = elasticTemplate.queryForPage(searchQuery, DiscussPost.class, new SearchResultMapper() {
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> aClass, Pageable pageable) {
                SearchHits hits = response.getHits();
                if (hits.getTotalHits() <= 0) {
                    return null;
                }

                List<DiscussPost> list = new ArrayList<>();
                for (SearchHit hit : hits) {
                    DiscussPost post = new DiscussPost();

                    String id = hit.getSourceAsMap().get("id").toString();
                    post.setId(Integer.valueOf(id));

                    String userId = hit.getSourceAsMap().get("userId").toString();
                    post.setUserId(Integer.valueOf(userId));

                    String title = hit.getSourceAsMap().get("title").toString();
                    post.setTitle(title);

                    String content = hit.getSourceAsMap().get("content").toString();
                    post.setContent(content);

                    String status = hit.getSourceAsMap().get("status").toString();
                    post.setStatus(Integer.valueOf(status));

                    String createTime = hit.getSourceAsMap().get("createTime").toString();
                    post.setCreateTime(new Date(Long.valueOf(createTime)));

                    String commentCount = hit.getSourceAsMap().get("commentCount").toString();
                    post.setCommentCount(Integer.valueOf(commentCount));

                    // 处理高亮显示的结果
                    HighlightField titleField = hit.getHighlightFields().get("title");
                    if (titleField != null) {
                        post.setTitle(titleField.getFragments()[0].toString());
                    }

                    HighlightField contentField = hit.getHighlightFields().get("content");
                    if (contentField != null) {
                        post.setContent(contentField.getFragments()[0].toString());
                    }

                    list.add(post);
                }

                return new AggregatedPageImpl(list, pageable,
                        hits.getTotalHits(), response.getAggregations(), response.getScrollId(), hits.getMaxScore());
            }
        });

        System.out.println(page.getTotalElements());
        System.out.println(page.getTotalPages());
        System.out.println(page.getNumber());
        System.out.println(page.getSize());
        for (DiscussPost post : page) {
            System.out.println(post);
        }

你可能感兴趣的:(ElasticSearch)