SpringBoot整合ElasticEearch【代码示例】

系列文章目录

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


文章目录

  • 系列文章目录
  • 项目下载地址
  • 一、引入依赖
  • 二、配置文件
  • 三、配置类
  • 四、实现操作
    • 1、创建实体类
    • 2、实现ElasticsearchRepository接口
    • 3、ProductRepositoryController
    • 4、ElasticSearchTemplateController


项目下载地址

SpringBoot整合Elasticsearch

ElasticEearch版本:7.10.2

一、引入依赖

<dependency>
  <groupId>org.springframework.bootgroupId>
  <artifactId>spring-boot-starter-data-elasticsearchartifactId>
  <version>2.4.5version>
dependency>

二、配置文件

spring:
  elasticsearch:
    ip: 127.0.0.1
    port: 9200

三、配置类

@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、创建实体类

@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:搜索时的分词器
     */

}

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);
    
}

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;
    }

}

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);
        }
    }

}

你可能感兴趣的:(springboot整合,spring,boot,elasticsearch,java)