Detailed steps for Spring Boot to integrate elasticsearch

  • 2021-07-13 05:13:03
  • OfStack

1. Introduction

Our applications often need to add retrieval functions, and the open source ElasticSearch is the first choice for full-text search engines at present. It can quickly store, search and analyze massive data. Spring Boot provides us with very convenient retrieval function support by integrating Spring Data ElasticSearch;

Elasticsearch is a distributed search service, providing Restful API, the bottom layer is based on Lucene, adopting multiple shard (fragmentation) to ensure data security, and providing automatic resharding function. Large sites such as github also adopt ElasticSearch as their search service,

We set up a website or application and add search functionality, but it is very difficult to complete the creation of search work. We want the search solution to run fast, We want to have a zero configuration and a completely free search mode. We want to be able to simply use JSON to index data through HTTP. We want our search server to be available all the time. We want to start with one and expand to hundreds. We want to search in real time. We want simple multi-tenants. We want to build a cloud solution. So we use Elasticsearch to solve all these problems and possibly more.

2. Install elasticsearch

We use the docker image installation method.


# Download image 
docker pull elasticsearch
# Start mirroring, elasticsearch  Startup will be assigned by default 2G Memory of   Our startup is set to be small 1 Point to prevent us from running out of memory and starting failure 
#9200 Yes elasticsearch  Default web Communication interface, 9300 Is distributed, elasticsearch Ports for communication between nodes 
docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9200:9200 -p 9300:9300 --name es01 5c1e1ecfe33a

Visit the following figure of 127.0. 0.1: 9200 to show that the installation was successful

3. Some concepts of elasticsearch

Take the storage in the form of employee documents as an example: 1 document represents 1 employee data. The behavior of storing data to ElasticSearch is called indexing, but before indexing a document, you need to determine where to store the document.

An ElasticSearch cluster can contain multiple indexes, each of which can contain multiple types. These different types store multiple documents, and each document has multiple attributes.

Similar relationship:

Index-database Type-table Document-record properties in table-column

The use of elasticsearch can refer to the official documents and will not be explained here.

4. Integrate elasticsearch

Create project springboot-elasticsearch and introduce web support

SpringBoot provides two ways to operate elasticsearch, Jest, and SpringData.

Jest Operation elasticsearch

Jest is the Java HTTP Rest client of ElasticSearch.

ElasticSearch already has an Java API, and ElasticSearch uses it internally, but Jest fills the gap and is the missing client for the ElasticSearch Http Rest interface.

1. 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.gf</groupId>
  <artifactId>springboot-elasticsearch</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>springboot-elasticsearch</name>
  <description>Demo project for Spring Boot</description>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.1.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </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-data-elasticsearch</artifactId>
  </dependency>
    <dependency>
      <groupId>io.searchbox</groupId>
      <artifactId>jest</artifactId>
      <version>5.3.3</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

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

2. application.properties


spring.elasticsearch.jest.uris=http://127.0.0.1:9200

3. Article


package com.gf.entity;
import io.searchbox.annotations.JestId;
public class Article {

  @JestId
  private Integer id;
  private String author;
  private String title;
  private String content;

  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  public String getAuthor() {
    return author;
  }

  public void setAuthor(String author) {
    this.author = author;
  }

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public String getContent() {
    return content;
  }

  public void setContent(String content) {
    this.content = content;
  }

  @Override
  public String toString() {
    final StringBuilder sb = new StringBuilder( "{\"Article\":{" );
    sb.append( "\"id\":" )
        .append( id );
    sb.append( ",\"author\":\"" )
        .append( author ).append( '\"' );
    sb.append( ",\"title\":\"" )
        .append( title ).append( '\"' );
    sb.append( ",\"content\":\"" )
        .append( content ).append( '\"' );
    sb.append( "}}" );
    return sb.toString();
  }
}

4. springboot test class


package com.gf;

import com.gf.entity.Article;
import io.searchbox.client.JestClient;
import io.searchbox.core.Index;
import io.searchbox.core.Search;
import io.searchbox.core.SearchResult;
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.test.context.junit4.SpringRunner;

import java.io.IOException;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootElasticsearchApplicationTests {

  @Autowired
  JestClient jestClient;

  @Test
  public void createIndex() {
    //1.  To ES Index in ( Save )1 Documents 
    Article article = new Article();
    article.setId( 1 );
    article.setTitle( " Good news " );
    article.setAuthor( " Zhang 3" );
    article.setContent( "Hello World" );

    //2.  Build 1 Index 
    Index index = new Index.Builder( article ).index( "gf" ).type( "news" ).build();
    try {
      //3.  Execute 
      jestClient.execute( index );
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Test
  public void search() {
    // Query expression 
    String query = "{\n" +
        "  \"query\" : {\n" +
        "    \"match\" : {\n" +
        "      \"content\" : \"hello\"\n" +
        "    }\n" +
        "  }\n" +
        "}";

    // Build the search function 
    Search search = new Search.Builder( query ).addIndex( "gf" ).addType( "news" ).build();

    try {
      // Execute 
      SearchResult result = jestClient.execute( search );
      System.out.println(result.getJsonString());
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

For more api of Jest, please refer to the document of github: https://github.com/searchbox-io/Jest

SpringData Operation elasticsearch

1. application.properties


spring.data.elasticsearch.cluster-name=elasticsearch
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300

2. Book


package com.gf.entity;
@Document( indexName = "gf" , type = "book")
public class Book {
  private Integer id;
  private String bookName;
  private String author;

  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  public String getBookName() {
    return bookName;
  }

  public void setBookName(String bookName) {
    this.bookName = bookName;
  }

  public String getAuthor() {
    return author;
  }

  public void setAuthor(String author) {
    this.author = author;
  }

  @Override
  public String toString() {
    final StringBuilder sb = new StringBuilder( "{\"Book\":{" );
    sb.append( "\"id\":" )
        .append( id );
    sb.append( ",\"bookName\":\"" )
        .append( bookName ).append( '\"' );
    sb.append( ",\"author\":\"" )
        .append( author ).append( '\"' );
    sb.append( "}}" );
    return sb.toString();
  }  
}

3. BookRepository


package com.gf.repository;
import com.gf.entity.Book;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import java.util.List;

public interface BookRepository extends ElasticsearchRepository<Book, Integer>{

  List<Book> findByBookNameLike(String bookName);
}

4. springboot test classes


package com.gf;
import com.gf.entity.Article;
import com.gf.entity.Book;
import com.gf.repository.BookRepository;
import io.searchbox.client.JestClient;
import io.searchbox.core.Index;
import io.searchbox.core.Search;
import io.searchbox.core.SearchResult;
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.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootElasticsearchApplicationTests {
  @Autowired
  BookRepository bookRepository;
  
  @Test
  public void createIndex2(){
    Book book = new Book();
    book.setId(1);
    book.setBookName(" Journey to the West ");
    book.setAuthor( " Wu Chengen " );
    bookRepository.index( book );
  }

  @Test
  public void useFind() {
    List<Book> list = bookRepository.findByBookNameLike( " Swim " );
    for (Book book : list) {
      System.out.println(book);
    }
  }
}

We started the test and found an error.

The reason for this error is that there is a conflict between the version of springData and my version of elasticsearch. In the afternoon, it is the adaptation table given in the official document of springData.

We are using springdata elasticsearch version 3.1. 3, the corresponding version should be 6.2. 2, and we are using elasticsearch version 5.6. 9, so we need to replace elasticsearch version 6. X at present


docker pull elasticsearch:6.5.1
docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9200:9200 -p 9300:9300 --name es02  Mirror image ID

Visit 127.0. 0.1: 9200

The cluster name is docker-cluster, so we will modify the configuration of application. properties


<?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.gf</groupId>
  <artifactId>springboot-elasticsearch</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>springboot-elasticsearch</name>
  <description>Demo project for Spring Boot</description>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.1.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </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-data-elasticsearch</artifactId>
  </dependency>
    <dependency>
      <groupId>io.searchbox</groupId>
      <artifactId>jest</artifactId>
      <version>5.3.3</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

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

We run the test again, and the test can pass. We visit http://127.0.0.1: 9200/gf/book/1 to get the index information we stored.

Source code: https://github.com/gf-huanchupk/SpringBootLearning


Related articles: