• SpringBoot 整合 Elasticsearch (超详细)


    SpringBoot 整合 Elasticsearch (超详细)

    注意:

    1、环境搭建

    安装es

    🔗Elasticsearch 6.4.3 下载链接

    为了方便,环境使用Windows

    配置

    🍑解压后配置

    • 找到config目录的elasticsearch.yml
    • image-20221109152237692

    分词器

    下图所示,解压后的分词器放在plugins目录下,ik目录需要自己创建

    image-20221109154446235

    启动

    • 🍈 由于我是在Windows环境下,找到bin目录的elasticsearch.bat双击即可。
    命令测试
    • 🚆 查看健康状态
      • curl -X GET “localhost:9200/_cat/health?v“
    • 🚖 查看所有节点
      • curl -X GET “localhost:9200/_cat/nodes?v“
    • 🏅 新建索引
      • curl -X PUT “localhost:9200/test”
    • ☀️ 查看索引
      • curl -X GET “localhost:9200/_cat/indices?v”
    • 🌈 删除索引
      • curl -X DELETE “localhost:9200/test”

    2、整合 Es

    依赖 & 配置

    • ❌ 我这里使用的是SpringBoot 2.1.5.RELEASE,根据实际情况选择版本。
    		
            <dependency>
                <groupId>org.springframework.datagroupId>
                <artifactId>spring-data-elasticsearchartifactId>
                <version>2.1.6.RELEASEversion>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • yaml配置

    image-20221109233533596

    • properties配置
    spring.data.elasticsearch.cluster-name=community
    spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300
    
    • 1
    • 2

    启动项目:

    • ❌ 不出意外肯定会出意外

    image-20221109234157966

    • ❓ 这个问题是由于Es底层的问题,这里就不展开解释,会提供思路,自行了解

    解决办法:

    image-20221109234326083

    3、使用

    SpringBoot 整合 Elasticsearch视频教程

    实体类

    • ❌ 相信之前学过Jpa的同学,对于以下配置很熟悉。
    import lombok.Data;
    import org.springframework.data.annotation.Id;
    import org.springframework.data.elasticsearch.annotations.Document;
    import org.springframework.data.elasticsearch.annotations.Field;
    import org.springframework.data.elasticsearch.annotations.FieldType;
    // 指定Es 索引 类型 分片 备份
    @Document(indexName = "discusspost", type = "_doc", shards = 6, replicas = 3)
    @Data
    public class DiscussPost implements Serializable {
        private static final long serialVersionUID = 114809849189593294L;
    
        // 标识主键
        @Id
        private Integer id;
    	
        // 对应文档类型
        @Field(type = FieldType.Integer)
        private Integer userId;
    
        /**
         * type 类型
         * analyzer 存储解析器
         * searchAnalyzer 查询解析器
         */
        @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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    持久层

    • ElasticsearchRepository 里面有许多常用方法
    @Repository
    public interface DiscussPostRepository extends ElasticsearchRepository<DiscussPost, Integer> {
    }
    
    • 1
    • 2
    • 3

    测试代码

    • ❌ 查询数据层的代码就不展示了,我会在代码中说明
    • 😊 时间足够,建议把视频看完
    /**
     * @author : look-word
     * 2022-11-03 18:56
     **/
    @SpringBootTest
    @RunWith(SpringRunner.class)
    public class ElasticSearchTest {
    
        @Resource
        private DiscussPostRepository discussPostRepository;
    
        @Resource
        private DiscussPostMapper discussPostMapper;
    
        @Resource
        private ElasticsearchTemplate elasticsearchTemplate;
    
        @Test
        public void testInsert() {
            // 将查询的结果,同步到Es中
            discussPostRepository.save(discussPostMapper.selectDiscussPostById(241));
        }
    
        @Test
        public void testInsertAll() {
            // 批量导入 discussPostRepository.saveAll()
            discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(101, 0, 100));
        }
    
        /**
         * 测试更新
         */
        @Test
        public void testUpdate() {
            DiscussPost discussPost = discussPostMapper.selectDiscussPostById(241);
            discussPost.setContent("我爱中华人民共和国,我是中国人");
            discussPostRepository.save(discussPost);
        }
    
        /**
         * 测试修改
         */
        @Test
        public void testDelete() {
            discussPostRepository.deleteById(241);
        }
    
        /**
         * 测试查询
         */
        @Test
        public void testSelect() {
            // 构造查询条件
            SearchQuery searchQuery = new NativeSearchQueryBuilder()
                	// (查询的值,查询字段1,查询字段1) 匹配title或者title里面是否含有互联网寒冬
                    .withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "title"))
                    .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(); //高亮
            Page<DiscussPost> page = discussPostRepository.search(searchQuery);
            page.get().forEach(System.out::println);
        }
    
        /**
         * 测试查询高亮显示
         */
        @Test
        public void testSelectHighlight() {
            // 构造查询条件
            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(); //高亮
    
            Page<DiscussPost> page = elasticsearchTemplate.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.parseInt(id));
    
                        String userId = hit.getSourceAsMap().get("userId").toString();
                        post.setUserId(Integer.parseInt(userId));
    
                        String title = hit.getSourceAsMap().get("title").toString();
                        post.setTitle(title);
    
                        String content = hit.getSourceAsMap().get("content").toString();
                        post.setContent(content);
    
                        String type = hit.getSourceAsMap().get("type").toString();
                        post.setType(Integer.parseInt(type));
    
                        String status = hit.getSourceAsMap().get("status").toString();
                        post.setStatus(Integer.parseInt(status));
    
                        String createTime = hit.getSourceAsMap().get("createTime").toString();
                        post.setCreateTime(new Date(Long.parseLong(createTime)));
    
                        String commentCount = hit.getSourceAsMap().get("commentCount").toString();
                        post.setCommentCount(Integer.parseInt(commentCount));
    
                        String score = hit.getSourceAsMap().get("score").toString();
                        post.setScore(Double.parseDouble(score));
    
                        // 处理高亮
                        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.setTitle(contentField.getFragments()[0].toString());
                        }
                        list.add(post);
                    }
                    return new AggregatedPageImpl(list, pageable, hits.getTotalHits(), response.getAggregations(), response.getScrollId(), hits.getMaxScore());
                }
            });
            page.get().forEach(System.out::println);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
  • 相关阅读:
    低代码开发平台有什么优势?
    从0到1:云计算工程师入门指南
    使用StanfordCoreNLP的句法树以及NLTK的Tree建立DGL的图数据结构
    请不要直接拆除或更换旧光纤!Softing为您提供光纤以太网网络解决方案
    Hadoop原理与技术——Hbase的基本操作
    Go 怎么操作 OSS 阿里云对象存储
    vue3 tsx语法
    C++面向对象:重写、重载、隐藏
    Tomcat-8.5_Apr-1.7构建
    Docker的开源容器镜像仓库Harbor安装
  • 原文地址:https://blog.csdn.net/qq_50975965/article/details/127780537