zoukankan      html  css  js  c++  java
  • Spring Boot 集成 Elasticsearch

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/15229906.html

    Project Directory

    Maven Dependency

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.3.12.RELEASE</version>
            <relativePath/>
        </parent>
    
        <groupId>org.fool.es</groupId>
        <artifactId>hello-spring-data-es</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
    </project>
    View Code

    application.properties

    server.port=8080
    
    logging.level.org.fool.es=debug
    
    elasticsearch.host=127.0.0.1
    elasticsearch.port=9200

    SRC

    Application.java

    package org.fool.es;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }

    ElasticsearchConfig.java

    package org.fool.es.config;
    
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    import org.apache.http.HttpHost;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
    
    @ConfigurationProperties(prefix = "elasticsearch")
    @Configuration
    @Data
    @EqualsAndHashCode(callSuper = true)
    public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {
        private String host;
        private Integer port;
    
        @Override
        public RestHighLevelClient elasticsearchClient() {
            return new RestHighLevelClient(RestClient.builder(new HttpHost(host, port)));
        }
    }

    使用 ElasticsearchRepository 进行通用的 CRUD

    Product.java

    package org.fool.es.index;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    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;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Document(indexName = "product", shards = 1, replicas = 1)
    public class Product {
        @Id
        private Long id;
        @Field(type = FieldType.Text, analyzer = "ik_max_word")
        private String title;
        @Field(type = FieldType.Keyword)
        private String category;
        @Field(type = FieldType.Double)
        private Double price;
        @Field(type = FieldType.Keyword, index = false)
        private String imageUrl;
    }

    ProductDAO.java

    package org.fool.es.dao;
    
    import org.fool.es.index.Product;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
    import org.springframework.stereotype.Repository;
    
    import java.util.List;
    
    @Repository
    public interface ProductDAO extends ElasticsearchRepository<Product, Long> {
        List<Product> findByTitle(String title);
    
        List<Product> findByTitle(String title, Pageable pageable);
    
        List<Product> findByTitleAndCategory(String title, String category);
    
        List<Product> findByTitleOrCategory(String title, String category);
    
    }

    SpringDataESTest.java

    package org.fool.es.test;
    
    import org.fool.es.dao.ProductDAO;
    import org.fool.es.index.Product;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.PageRequest;
    import org.springframework.data.domain.Sort;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import java.util.ArrayList;
    import java.util.List;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class SpringDataESTest {
    
        @Autowired
        private ProductDAO productDAO;
    
        ......
    }

    insert

    @Test
    public void testInsert() {
        Product product = new Product();
        product.setId(1001L);
        product.setTitle("iPhone X");
        product.setCategory("mobile");
        product.setPrice(6999.0);
        product.setImageUrl("http://www.apple.com/iPhone.jpg");
        productDAO.save(product);
    }

    update

    @Test
    public void testUpdate() {
        Product product = new Product();
        product.setId(1001L);
        product.setTitle("iPhone X Max");
        product.setCategory("mobile");
        product.setPrice(8999.0);
        product.setImageUrl("http://www.apple.com/iPhone.jpg");
        productDAO.save(product);
    }

    delete

    @Test
    public void testDelete() {
        Product product = new Product();
        product.setId(1001L);
        productDAO.delete(product);
    }

    batchInsert

    @Test
    public void testBatchInsert() {
        List<Product> productList = new ArrayList<>();
    
        for (int i = 0; i < 10; i++) {
            Product product = new Product();
            product.setId((long) i);
            product.setTitle("iPhone " + i);
            product.setCategory("mobile");
            product.setPrice(6999.0 + i);
            product.setImageUrl("http://www.apple.com/iPhone.jpg");
            productList.add(product);
        }
    
        productDAO.saveAll(productList);
    }

    findById

    @Test
    public void testFindById() {
        productDAO.findById(1001L).ifPresent(System.out::println);
    }

    findAll

    @Test
    public void testFindAll() {
        productDAO.findAll().forEach(System.out::println);
    }

    findByPageable

    @Test
    public void findByPageable() {
        Sort sort = Sort.by(Sort.Direction.DESC, "id");
        int currentPage = 0;
        int pageSize = 5;
    
        PageRequest pageRequest = PageRequest.of(currentPage, pageSize, sort);
    
        Page<Product> results = productDAO.findAll(pageRequest);
    
        System.out.println(results.getTotalPages());
        System.out.println(results.getSize());
        System.out.println(results.getNumber());
    
        results.getContent().forEach(System.out::println);
    }

    findByTitle

    @Test
    public void testFindByTitle() {
        productDAO.findByTitle("iPhone 8").forEach(System.out::println);
    }

    findByTitleWithPagination

    @Test
    public void testFindByTitleWithPagination() {
        productDAO.findByTitle("iPhone", PageRequest.of(0, 5)).forEach(System.out::println);
    }

    findByTitleOrCategory

    @Test
    public void testFindByTitleOrCategory() {
        productDAO.findByTitleOrCategory("iPhone", "mobile").forEach(System.out::println);
    }

    findByTitleAndCategory

    @Test
    public void testFindByTitleAndCategory() {
        productDAO.findByTitleAndCategory("iPhone", "pad").forEach(System.out::println);
    }

    使用 NativeSearchQuery 进行复杂查询

    User.java

    package org.fool.es.index;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    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;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Document(indexName = "user", shards = 1, replicas = 1)
    public class User {
        @Id
        private Long id;
        @Field(type = FieldType.Text, analyzer = "ik_max_word")
        private String name;
        @Field(type = FieldType.Keyword)
        private String sex;
        @Field(type = FieldType.Integer)
        private Integer age;
        @Field(type = FieldType.Text, analyzer = "ik_max_word")
        private String address;
    }

    UserDAO.java

    package org.fool.es.dao;
    
    import org.fool.es.index.User;
    import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
    import org.springframework.stereotype.Repository;
    
    @Repository
    public interface UserDAO extends ElasticsearchRepository<User, Long> {
    
    }

    SpringESNativeSearchQueryTest.java

    package org.fool.es.test;
    
    import org.elasticsearch.common.unit.Fuzziness;
    import org.elasticsearch.index.query.MatchAllQueryBuilder;
    import org.elasticsearch.index.query.QueryBuilders;
    import org.elasticsearch.search.aggregations.AggregationBuilders;
    import org.elasticsearch.search.aggregations.Aggregations;
    import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms;
    import org.elasticsearch.search.aggregations.bucket.terms.Terms;
    import org.elasticsearch.search.aggregations.metrics.ParsedMax;
    import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
    import org.elasticsearch.search.sort.SortBuilders;
    import org.elasticsearch.search.sort.SortOrder;
    import org.fool.es.dao.UserDAO;
    import org.fool.es.index.User;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.data.domain.PageRequest;
    import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
    import org.springframework.data.elasticsearch.core.SearchHit;
    import org.springframework.data.elasticsearch.core.SearchHits;
    import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
    import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
    import org.springframework.data.elasticsearch.core.query.SourceFilter;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import java.util.ArrayList;
    import java.util.List;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class SpringESNativeSearchQueryTest {
    
        @Autowired
        private UserDAO userDAO;
    
        @Autowired
        private ElasticsearchRestTemplate elasticsearchRestTemplate;
    
        @Test
        public void testBatchInsert() throws Exception {
            List<User> recordList = new ArrayList<>();
            recordList.add(new User(1001L, "caocao", "male", 10, "shanghai"));
            recordList.add(new User(1002L, "liubei", "male", 20, "beijing"));
            recordList.add(new User(1003L, "sunquan", "male", 30, "shenzhen"));
            recordList.add(new User(1004L, "guanyu", "male", 40, "guangzhou"));
            recordList.add(new User(1005L, "zhangfei", "male", 40, "shanghai"));
            recordList.add(new User(1006L, "zhaoyun", "male", 50, "beijing"));
            recordList.add(new User(1007L, "caocao2", "female", 50, "chengdu"));
    
            userDAO.saveAll(recordList);
        }
    
        @Test
        public void testDelete() {
            userDAO.deleteAll();
        }
    
        ......
    
    }

    Note:

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    queryAll

    @Test
    public void testQueryAll() {
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(new MatchAllQueryBuilder())
                .build();
    
        SearchHits<User> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, User.class);
    
        long count = searchHits.getTotalHits();
        System.out.println(count);
        List<SearchHit<User>> list = searchHits.getSearchHits();
        for (SearchHit<User> record : list) {
            System.out.println(record.getContent());
        }
    }

    queryString

    @Test
    public void testQueryString() {
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                // query field address
                .withQuery(QueryBuilders.queryStringQuery("shanghai").defaultField("address"))
                // query all field
                //.withQuery(QueryBuilders.queryStringQuery("shanghai"))
                // query field name, address
                //.withQuery(QueryBuilders.queryStringQuery("shanghai").field("name").field("address"))
                .build();
    
        SearchHits<User> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, User.class);
    
        long count = searchHits.getTotalHits();
        System.out.println(count);
        List<SearchHit<User>> list = searchHits.getSearchHits();
        for (SearchHit<User> record : list) {
            System.out.println(record.getContent());
        }
    }

    queryTerm

    @Test
    public void testQueryTerm() {
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.termQuery("name", "caocao"))
                .build();
    
        SearchHits<User> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, User.class);
    
        long count = searchHits.getTotalHits();
        System.out.println(count);
        List<SearchHit<User>> list = searchHits.getSearchHits();
        for (SearchHit<User> record : list) {
            System.out.println(record.getContent());
        }
    }

    queryPagination

    @Test
    public void testQueryPagination() {
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchAllQuery())
                .withPageable(PageRequest.of(0, 5))
                .build();
    
        SearchHits<User> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, User.class);
    
        long count = searchHits.getTotalHits();
        System.out.println(count);
        List<SearchHit<User>> list = searchHits.getSearchHits();
        for (SearchHit<User> record : list) {
            System.out.println(record.getContent());
        }
    }

    querySort

    @Test
    public void testQuerySort() {
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchAllQuery())
                .withPageable(PageRequest.of(0, 5))
                .withSort(SortBuilders.fieldSort("id").order(SortOrder.DESC))
                .build();
    
        SearchHits<User> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, User.class);
    
        long count = searchHits.getTotalHits();
        System.out.println(count);
        List<SearchHit<User>> list = searchHits.getSearchHits();
        for (SearchHit<User> record : list) {
            System.out.println(record.getContent());
        }
    }

    queryFilter

    @Test
    public void testQueryFilter() {
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchAllQuery())
                .withPageable(PageRequest.of(0, 5))
                .withSourceFilter(new SourceFilter() {
                    @Override
                    public String[] getIncludes() {
                        return new String[]{"name"};
                    }
    
                    @Override
                    public String[] getExcludes() {
                        return new String[]{};
                    }
                }).build();
    
        SearchHits<User> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, User.class);
    
        long count = searchHits.getTotalHits();
        System.out.println(count);
        List<SearchHit<User>> list = searchHits.getSearchHits();
        for (SearchHit<User> record : list) {
            System.out.println(record.getContent());
        }
    }

    queryBool

    @Test
    public void testQueryBool() {
        // or
        //NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
        //        .withQuery(QueryBuilders.boolQuery()
        //                .should(QueryBuilders.termQuery("age", 30))
        //                .should(QueryBuilders.termQuery("sex", "female")))
        //        .build();
    
        // and
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.boolQuery()
                        .must(QueryBuilders.termQuery("age", 30))
                        .must(QueryBuilders.termQuery("sex", "male")))
                .build();
    
        SearchHits<User> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, User.class);
    
        long count = searchHits.getTotalHits();
        System.out.println(count);
        List<SearchHit<User>> list = searchHits.getSearchHits();
        for (SearchHit<User> record : list) {
            System.out.println(record.getContent());
        }
    }

    queryRange

    @Test
    public void testQueryRange() {
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.rangeQuery("age").gte(30).lte(50))
                .build();
    
        SearchHits<User> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, User.class);
    
        long count = searchHits.getTotalHits();
        System.out.println(count);
        List<SearchHit<User>> list = searchHits.getSearchHits();
        for (SearchHit<User> record : list) {
            System.out.println(record.getContent());
        }
    }

    queryFuzzy

    @Test
    public void testQueryFuzzy() {
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.fuzzyQuery("name", "caocao").fuzziness(Fuzziness.ONE))
                .build();
    
        SearchHits<User> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, User.class);
    
        long count = searchHits.getTotalHits();
        System.out.println(count);
        List<SearchHit<User>> list = searchHits.getSearchHits();
        for (SearchHit<User> record : list) {
            System.out.println(record.getContent());
        }
    }

    queryHighlight

    @Test
    public void testQueryHighlight() {
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.termQuery("name", "caocao"))
                .withHighlightFields(new HighlightBuilder.Field("name").preTags("<font color='red'>").postTags("</font>"))
                .build();
    
        SearchHits<User> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, User.class);
    
        long count = searchHits.getTotalHits();
        System.out.println(count);
        List<SearchHit<User>> list = searchHits.getSearchHits();
        for (SearchHit<User> record : list) {
            System.out.println(record.getContent());
            System.out.println(record.getHighlightFields());
        }
    }

    queryAggregation

    @Test
    public void testQueryAggregation() {
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .addAggregation(AggregationBuilders.max("maxAge").field("age"))
                .build();
    
        SearchHits<User> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, User.class);
    
        long count = searchHits.getTotalHits();
        System.out.println(count);
    
        Aggregations aggregations = searchHits.getAggregations();
        assert aggregations != null;
        ParsedMax terms = aggregations.get("maxAge");
        System.out.println(terms.getValue());
    }

    queryGroup

    @Test
    public void testQueryGroup() {
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .addAggregation(AggregationBuilders.terms("ageGroup").field("age"))
                .build();
    
        SearchHits<User> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, User.class);
    
        long count = searchHits.getTotalHits();
        System.out.println(count);
    
        Aggregations aggregations = searchHits.getAggregations();
        assert aggregations != null;
        ParsedLongTerms terms = aggregations.get("ageGroup");
        List<? extends Terms.Bucket> buckets = terms.getBuckets();
        for (Terms.Bucket bucket : buckets) {
            System.out.println(bucket.getKey() + ":" + bucket.getDocCount());
        }
    }

    Reference

    https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.repositories


    欢迎点赞关注和收藏

    强者自救 圣者渡人
  • 相关阅读:
    变量的创建和初始化
    HDU 1114 Piggy-Bank (dp)
    HDU 1421 搬寝室 (dp)
    HDU 2059 龟兔赛跑 (dp)
    HDU 2571 命运 (dp)
    HDU 1574 RP问题 (dp)
    HDU 2577 How to Type (字符串处理)
    HDU 1422 重温世界杯 (dp)
    HDU 2191 珍惜现在,感恩生活 (dp)
    HH实习 acm算法部 1689
  • 原文地址:https://www.cnblogs.com/agilestyle/p/15229906.html
Copyright © 2011-2022 走看看