Springboot 2.x integration ElasticSearch6.x

SpringBoot integration with ElasticSearch is simple, simply by introducing a spring-data-elasticsearch dependency and adding a configuration.
Because Elasticsearch has many versions, it is now available 7.5.x, spring-data-elasticsearch is compatible with the corresponding version as follows:

 

Project structure

 

pom.xml

<?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>

    <groupId>com.piao</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>es-demo</name>
    <description>ElasticSearch Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--elasticsearch-->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-elasticsearch</artifactId>
            <version>3.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>
        <!--<dependency>-->
            <!--<groupId>junit</groupId>-->
            <!--<artifactId>junit</artifactId>-->
            <!--<scope>test</scope>-->
        <!--</dependency>-->

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

 

application.yml

elasticsearch:
    host: 127.0.0.1
    port: 9300
    clustername: piao
    search:
        pool:
            size: 5

 

ElasticsearchConfig

package com.piao.config;

import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;

import java.net.InetAddress;

@Slf4j
@Configuration
@EnableElasticsearchRepositories(basePackages = "com.piao.dao")
public class ElasticsearchConfig {

    @Value("${elasticsearch.host}")
    private String host;

    @Value("${elasticsearch.port}")
    private int port;

    @Value("${elasticsearch.clustername}")
    private String clusterName;

    @Value("${elasticsearch.search.pool.size}")
    private Integer threadPoolSearchSize;

    @Bean
    public Client client() throws Exception {
        Settings esSettings = Settings.builder()
                .put("cluster.name", clusterName)
                //Increase sniffing mechanism, find ES cluster, non-cluster set to false
                .put("client.transport.sniff", true)
                //Increase the number of thread pools
                .put("thread_pool.search.size", threadPoolSearchSize)
                .build();
        return new PreBuiltTransportClient(esSettings)
                //You do not need to configure a host and port if you do not need to set up an ES cluster.I have configured the hosts and ports of the ES cluster here
                .addTransportAddress(new TransportAddress(InetAddress.getByName(host), port));
    }

    @Bean
    public ElasticsearchTemplate elasticsearchTemplate() throws Exception {
        try {
            return new ElasticsearchTemplate(client());
        } catch (Exception e) {
            log.error("Initialization ElasticsearchTemplate fail");
            return new ElasticsearchTemplate(client());
        }
    }
}

 

CostumeRepository

package com.piao.dao;

import com.piao.entity.Costume;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CostumeRepository extends ElasticsearchRepository<Costume, String> {

}

 

Costume

package com.piao.entity;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import java.math.BigDecimal;
import java.util.Date;

@Data
@Document(indexName = "goods", type = "costume", useServerConfiguration = true, createIndex = false)
public class Costume {

    @Id
    private String id;

    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_max_word")
    private String name;

    @Field(type = FieldType.Integer)
    private Integer num;

    @Field(type = FieldType.Double)
    private BigDecimal price;

    @Field(type = FieldType.Integer)
    private Integer type;

    @Field(type = FieldType.Date, pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis", format = DateFormat.custom)
    private Date date;

    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_max_word")
    private String describe;


}

Explanation of the related spring-data-elasticsearch annotations used in the above class:
@Document Represents a document in the definition ES

  • The indexName index name, typically in all lowercase letters, can be thought of as the database name
  • type, which can be thought of as a database table name
  • Whether useServerConfiguration uses system configuration
  • shards Cluster mode with 5 slices by default
  • replicas Data Copy Several Copies, Default 1 Copy
  • How often refreshInterval refreshes data, default 1s
  • indexStoreType index storage mode, default FS
  • createIndex Whether to create an index, default True, represents automatic creation when there is no corresponding index for indexName

@Field The field type in the document, which corresponds to the document's Mapping concept in ES, is to set the field type

  • Type field type, inferred by default by java type, or specified manually, enumerated by FieldType

  • Index Whether to create an inverted index for each field, default true, set to false if you don't want to query the document through a field's keyword

  • pattern is used on date type field format =DateFormat.customPattern = "yyyy-MM-dd HH:mm:ss:SSS"

  • searchAnalyzer specifies the participle of the search, and the IK participle is only ik_Smart (coarse grained) and ik_Max_Word (fine-grained) two modes, specific differences you can go to the IK official website to see

  • analyzer Specifies the segmenter for the index. The IK segmenter has ik_smart and ik_max_word

  • Whether store is stored in _of the documentSource field, not stored by default false

 

CostumeTest

package com.piao;

import com.piao.dao.CostumeRepository;
import com.piao.entity.Costume;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
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.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.test.context.junit4.SpringRunner;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Iterator;
import java.util.Optional;
import java.util.UUID;

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class CostumeTest {

    @Autowired
    CostumeRepository goodsRepository;

    @Test
    public void saveCostume(){
        Costume costume = new Costume();
        costume.setId(UUID.randomUUID().toString());
        costume.setDate(new Date());
        costume.setName("Taiping Bird Swallow Tail Suit");
        costume.setDescribe("Time-limited discount Taiping bird swallow tail clothes, sold at 8% discount");
        goodsRepository.save(costume);

        System.out.println(costume.getId());
    }

    @Test
    public void updateCostume(){
        String id = "d1e18d38-1763-4aa8-a274-e0a6737f7519";
        Optional<Costume> itemOptional = goodsRepository.findById(id);
        Costume costume = itemOptional.get();
        costume.setNum(20);
        costume.setPrice(new BigDecimal("680.50"));
        goodsRepository.save(costume);
    }

    @Test
    public void deleteCostume(){
        Costume costume = new Costume();
        costume.setId("bd057656-e0f8-4b49-9ed8-045712d06c83");

        goodsRepository.delete(costume);
    }

    /**
     * Query by Id
     */
    @Test
    public void findGoodsById() {
        Optional<Costume> goods = goodsRepository.findById("2");
        System.out.println(goods.get());
    }

    /**
     * Word Segmentation Query
     */
    @Test
    public void findCostumeByName() {
        String keyWord = "Gym shoes";
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", keyWord);
        Iterable<Costume> search = goodsRepository.search(matchQueryBuilder);

        Iterator<Costume> iterator = search.iterator();
        while (iterator.hasNext()) {
            Costume next = iterator.next();
            System.out.println(next);
        }
    }

    /**
     * Full Match Query
     */
    @Test
    public void findCostumeByNam2() {
        String keyWord = "Taiping Bird";
        MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery("name", keyWord);
        Iterable<Costume> search = goodsRepository.search(matchPhraseQueryBuilder);

        Iterator<Costume> iterator = search.iterator();
        while (iterator.hasNext()) {
            Costume next = iterator.next();
            System.out.println(next);
        }
    }

    /**
     * Paging Query
     */
    @Test
    public void findCostumeByNamPage() {
        Sort date = Sort.by("date").ascending();
        Pageable pageable = PageRequest.of(0, 5, date);

        String keyWord = "Taipingbird sneakers";
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", keyWord);
        Iterable<Costume> search = goodsRepository.search(matchQueryBuilder, pageable);

        Iterator<Costume> iterator = search.iterator();
        while (iterator.hasNext()) {
            Costume next = iterator.next();
            System.out.println(next);
        }
    }

}

 

Read more

ElasticSearch Learning Summary

Chapter 7: ElasticSearch Advanced Query

Tags: Big Data ElasticSearch Java Spring Junit

Posted on Sun, 17 May 2020 11:14:30 -0700 by Houdini