• SpringBoot整合ElasticEearch【代码示例】


    系列文章目录

    一、SpringBoot连接MySQL数据库实例【tk.mybatis连接mysql数据库】
    二、SpringBoot连接Redis与Redisson【代码】
    三、SpringBoot整合WebSocket【代码】
    四、SpringBoot整合ElasticEearch【代码示例】



    项目下载地址

    SpringBoot整合Elasticsearch

    ElasticEearch版本:7.10.2

    一、引入依赖

    <dependency>
      <groupId>org.springframework.bootgroupId>
      <artifactId>spring-boot-starter-data-elasticsearchartifactId>
      <version>2.4.5version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    二、配置文件

    spring:
      elasticsearch:
        ip: 127.0.0.1
        port: 9200
    
    • 1
    • 2
    • 3
    • 4

    三、配置类

    @Configuration
    public class ElasticSearchConfig {
    
        @Value("${spring.elasticsearch.ip}")
        private String esIp;
    
        @Value("${spring.elasticsearch.port}")
        private Integer port;
    
        @Bean
        public RestHighLevelClient restHighLevelClient() {
            RestHighLevelClient client = new RestHighLevelClient(
                    RestClient.builder(
                            new HttpHost(esIp, port, "http")
                    )
            );
            return client;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    四、实现操作

    1、创建实体类

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Document(indexName = "product", createIndex = true)
    public class Product {
    
        @Id
        @Field(type = FieldType.Integer, store = true, index = true)
        private Integer id;
    
        @Field(type = FieldType.Text, store = true, index = true, analyzer = "ik_max_word", searchAnalyzer = "ik_max_word")
        private String productName;
    
        @Field(type = FieldType.Text, store = true, index = true, analyzer = "ik_max_word", searchAnalyzer = "ik_max_word")
        private String productDesc;
    
    
        /*
                @Document:标记在类上,标记实体类为文档对象,一般有如下属性:
    
                indexName:对应索引的名称
    
                createIndex:是否自动创建索引
    
                @Id:标记在成员变量上,标记一个字段为主键,该字段的值会同步到ES该文档的id值。
    
                @Field:标记在成员变量上,标记为文档中的域,一般有如下属性:
    
                type:域的类型
    
                index:是否创建索引,默认是 true
    
                store:是否单独存储,默认是 false
    
                analyzer:分词器
    
                searchAnalyzer:搜索时的分词器
         */
    
    }
    
    • 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

    2、实现ElasticsearchRepository接口

    在下面的代码中已经书写了 DSL查询方法、按照命规则的查询方法、分页查询以及高亮查询

    public interface ProductRepository extends ElasticsearchRepository<Product, Integer> {
    
        /**
         * @author Lee
         * @date 2023/9/10 17:11
         * @description DSL查询
         */
        @Query("{" +
                "   \"match\": {" +
                "    \"productDesc\": \"?0\"" +
                "   }" +
                "  }")
        List<Product> findByProductDescMatch(String keyword);
    
        @Query("{" +
                " \"match\": {" +
                "  \"productDesc\": {" +
                "   \"query\": \"?0\"," +
                "   \"fuzziness\": 1" +         // 自动纠错
                "  }" +
                " }" +
                "}")
        List<Product> findByProductDescFuzzy(String keyword);
    
        /**
         * @author Lee
         * @date 2023/9/10 17:12
         * @description 按照规则命名查询  查询方法以findBy开头,涉及查询条件时,条件的属性用条件关键字连接。
         */
        List<Product> findByProductName(String productName);
    
        List<Product> findByProductNameOrProductDesc(String productName, String productDesc);
    
        List<Product> findByIdBetween(Integer startId,Integer endId);
    
        /**
         * @author Lee
         * @date 2023/9/10 17:18
         * @description 分页查询
         */
        Page<Product> findByProductDesc(String productDesc, Pageable pageable);
    
    
        /**
         * @author Lee
         * @date 2023/9/10 17:56
         * @description 高亮
         */
        @Highlight(fields = {@HighlightField(name = "title"), @HighlightField(name = "content")})
        List<SearchHit<Product>> findByTitleMatchesOrContentMatches(String title, 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
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    3、ProductRepositoryController

    该类展示了repository接口方法的使用

    @RestController
    @RequestMapping("/test")
    public class ProductRepositoryController {
    
        @Autowired
        private ProductRepository repository;
    
        @RequestMapping("/addDocument")
        public void addDocument(){
            Product product = new Product(1, "测试1", "Elaticsearch,简称为es,es是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别(大数据时代)的数据");
            repository.save(product);
        }
    
        @RequestMapping("/updateDocument")
        public void updateDocument(){
            Product product = new Product(1, "测试1", "Elaticsearch,简称为es,es是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别(大数据时代)的数据");
            repository.save(product);
        }
    
        @RequestMapping("/findAllDocument")
        public void findAllDocument(){
            Iterable<Product> all = repository.findAll();
            for (Product product : all) {
                System.out.println(product);
            }
        }
    
        @RequestMapping("/findDocumentById")
        public void findDocumentById(){
            Optional<Product> product = repository.findById(1);
            System.out.println(product.get());
        }
    
        @RequestMapping("/deleteDocument")
        public void deleteDocument(){
            repository.deleteById(1);
        }
    
        /**
         * @author Lee
         * @date 2023/9/10 17:39
         * @description DSL查询
         */
        @RequestMapping("/findByProductDescMatch")
        public void findByProductDescMatch(){
            repository.findByProductDescMatch("测试1");
        }
    
        @RequestMapping("/findByProductDescFuzzy")
        public void findByProductDescFuzzy(){
            repository.findByProductDescFuzzy("测试1");
        }
    
    
        /**
         * @author Lee
         * @date 2023/9/10 17:15
         * @description 分页查询
         */
        public void findPage(){
            // 参数1:页数   参数2:每页条数
            Pageable pageable = PageRequest.of(1, 3);
            Page<Product> page = repository.findAll(pageable);
            System.out.println("总条数"+page.getTotalElements());
            System.out.println("总页数"+page.getTotalPages());
            System.out.println("数据"+page.getContent());
        }
    
        public void findPage2(){
            Pageable pageable = PageRequest.of(1, 2);
            Page<Product> page = repository.findByProductDesc("测试1", pageable);
            System.out.println("总条数"+page.getTotalElements());
            System.out.println("总页数"+page.getTotalPages());
            System.out.println("数据"+page.getContent());
        }
    
    
        /**
         * @author Lee
         * @date 2023/9/10 17:39
         * @description 结果排序
         */
        public void testFindSort(){
            Sort sort = Sort.by(Sort.Direction.DESC, "id");
            Iterable<Product> all = repository.findAll(sort);
            for (Product product : all) {
                System.out.println(product);
            }
        }
    
        /**
         * @author Lee
         * @date 2023/9/10 17:41
         * @description 分页加排序
         */
        public void testFindPage2(){
            Sort sort = Sort.by(Sort.Direction.DESC,"id");
            Pageable pageable = PageRequest.of(0, 2,sort);
            Page<Product> page = repository.findByProductDesc("测试1", pageable);
            System.out.println("总条数"+page.getTotalElements());
            System.out.println("总页数"+page.getTotalPages());
            System.out.println("数据"+page.getContent());
        }
    
    	/** 
         * @author Lee
         * @date 2023/9/10 17:58
         * @description 高亮
         */
        @RequestMapping("/highLightSearch")
        public List<Product> highLightSearch(String keyword){
            List<SearchHit<Product>> result = repository.findByTitleMatchesOrContentMatches(keyword, keyword);
            // 处理结果,封装为Product类型的集合
            List<Product> newsList = new ArrayList();
            for (SearchHit<Product> productSearchHit : result) {
                Product Product = productSearchHit.getContent();
                // 高亮字段
                Map<String, List<String>> highlightFields = productSearchHit.getHighlightFields();
                if (highlightFields.get("title") != null){
                    Product.setProductName(highlightFields.get("title").get(0));
                }
                if (highlightFields.get("content") != null){
                    Product.setProductDesc(highlightFields.get("content").get(0));
                }
                newsList.add(Product);
            }
            return newsList;
        }
    
    }
    
    • 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

    4、ElasticSearchTemplateController

    该类展示了template模板提供的方法

    @RestController
    @RequestMapping("/testTemplate")
    public class ElasticSearchTemplateController {
    
        @Autowired
        private ElasticsearchRestTemplate template;
    
        // 操作索引
        /**
         * @author Lee
         * @date 2023/9/10 17:47
         * @description 新增索引
         */
        @RequestMapping("/addIndex")
        public void addIndex(){
            // 获得索引操作对象
            IndexOperations indexOperations = template.indexOps(Product.class);
            // 创建索引,注:该方法无法设置索引结构,不推荐使用
            indexOperations.create();
        }
    
        /**
         * @author Lee
         * @date 2023/9/10 17:47
         * @description 删除索引
         */
        @RequestMapping("/delIndex")
        public void delIndex(){
            // 获得索引操作对象
            IndexOperations indexOperations = template.indexOps(Product.class);
            // 删除索引
            indexOperations.delete();
        }
    
        // 操作文档
        /**
         * @author Lee
         * @date 2023/9/10 17:48
         * @description 新增/修改
         */
        @RequestMapping("/addDocument")
        public void addDocument(){
            Product product = new Product(10, "es1", "es是一款优秀的搜索引擎");
            template.save(product);
        }
    
        /**
         * @author Lee
         * @date 2023/9/10 17:49
         * @description 删除
         */
        @RequestMapping("/delDocument")
        public void delDocument(){
            template.delete("10",Product.class);
        }
    
        /**
         * @author Lee
         * @date 2023/9/10 17:50
         * @description 查询
         */
        @RequestMapping("/searchDocument")
        public void searchDocument(){
            // 1.确定查询方式
            // MatchAllQueryBuilder builder = QueryBuilders.matchAllQuery();
            // TermQueryBuilder builder = QueryBuilders.termQuery("productDesc", "搜索引擎");
            MatchQueryBuilder builder = QueryBuilders.matchQuery("productDesc", "搜索引擎");
            // 2.构建查询条件
            NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(builder).build();
            // 3.查询
            SearchHits<Product> result = template.search(query, Product.class);
            // 4.处理查询结果
            for (SearchHit<Product> productSearchHit : result) {
                Product product = productSearchHit.getContent();
                System.out.println(product);
            }
        }
    
        /**
         * @author Lee
         * @date 2023/9/10 17:51
         * @description 复杂查询
         */
        @RequestMapping("/searchDocument2")
        public void searchDocument2() {
            //     String productName = "elasticsearch";
            //     String productDesc = "优秀";
            String productName = null;
            String productDesc = null;
    
            // 1.确定查询方式
            BoolQueryBuilder builder = QueryBuilders.boolQuery();
            // 如果没有传入参数,查询所有
            if (productName == null && productDesc == null) {
                MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
                builder.must(matchAllQueryBuilder);
            } else {
                if (productName != null && productName.length() > 0) {
                    MatchQueryBuilder queryBuilder1 = QueryBuilders.matchQuery("productName", productName);
                    builder.must(queryBuilder1);
                }
                if (productDesc != null && productDesc.length() > 0) {
                    MatchQueryBuilder queryBuilder2 = QueryBuilders.matchQuery("productDesc", productDesc);
                    builder.must(queryBuilder2);
                }
            }
    
            // 2.构建查询条件
            NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(builder).build();
    
            // 3.查询
            SearchHits<Product> result = template.search(query, Product.class);
    
            // 4.处理查询结果
            for (SearchHit<Product> productSearchHit : result) {
                Product product = productSearchHit.getContent();
                System.out.println(product);
            }
        }
    
        /**
         * @author Lee
         * @date 2023/9/10 17:53
         * @description 分页查询
         */
        @RequestMapping("/searchDocumentPage")
        public void searchDocumentPage() {
            // 1.确定查询方式
            MatchAllQueryBuilder builder = QueryBuilders.matchAllQuery();
    
            // 2.构建查询条件
            // 分页条件
            Pageable pageable = PageRequest.of(0, 3);
            NativeSearchQuery query = new NativeSearchQueryBuilder()
                    .withQuery(builder)
                    .withPageable(pageable)
                    .build();
    
            // 3.查询
            SearchHits<Product> result = template.search(query, Product.class);
    
            // 4.将查询结果封装为Page对象
            List<Product> content = new ArrayList();
            for (SearchHit<Product> productSearchHit : result) {
                Product product = productSearchHit.getContent();
                content.add(product);
            }
            /**
             * 封装Page对象,参数1:具体数据,参数2:分页条件对象,参数3:总条数
             */
            Page<Product> page = new PageImpl(content, pageable, result.getTotalHits());
    
            System.out.println(page.getTotalElements());
            System.out.println(page.getTotalPages());
            System.out.println(page.getContent());
        }
    
        /**
         * @author Lee
         * @date 2023/9/10 17:54
         * @description 结果排序
         */
        @RequestMapping("/searchDocumentSort")
        public void searchDocumentSort() {
            // 1.确定查询方式
            MatchAllQueryBuilder builder = QueryBuilders.matchAllQuery();
    
            // 2.构建查询条件
            // 排序条件
            SortBuilder sortBuilder = SortBuilders.fieldSort("id").order(SortOrder.DESC);
            NativeSearchQuery query = new NativeSearchQueryBuilder()
                    .withQuery(builder)
                    .withSort(sortBuilder)
                    .build();
    
            // 3.查询
            SearchHits<Product> result = template.search(query, Product.class);
    
            // 4.处理查询结果
            for (SearchHit<Product> productSearchHit : result) {
                Product product = productSearchHit.getContent();
                System.out.println(product);
            }
        }
    
    }
    
    
    • 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
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
  • 相关阅读:
    SpringBoot初始化数据的一些方法
    Windows模拟器推荐
    IOday3作业
    计算机网络
    KMP 算法
    HDLBis-Fsm3s
    【Java初阶】- - - static 关键字
    修改原生checkbox的样式
    前端面试题目(二十三)
    The Best of Many Worlds_ Dual Mirror Descent for Online Allocation Problems
  • 原文地址:https://blog.csdn.net/weixin_49832841/article/details/132793868