Elasticsearch: connect elasticsearch from the Spring Boot application

Keywords: ElasticSearch Spring Spring Boot elastic

In previous articles“ Elasticsearch: use Spring Boot to create REST APIs to access elasticsearch ”, I described in detail how to use it in Spring Boot applications   Elasticsearch rest high level client library to connect with elasticsearch. In today's article, I'll use another library   spring-boot-starter-data-elasticsearch   To connect to elasticsearch. This method is very simple and direct.

For your convenience, I put the final code into github   GitHub - liu-xiao-guo/SpringBootElasticsearch-demo . You can get it in the following ways:

git clone https://github.com/liu-xiao-guo/SpringBootElasticsearch-demo

Code interpretation

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 https://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.5.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.liuxg</groupId>
    <artifactId>SpringBootElasticsearch-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SpringBootElasticsearch-demo</name>
    <description>SpringBootElasticsearch-demo</description>
    <properties>
        <java.version>1.8</java.version>
        <elastic.version>7.15.0</elastic.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </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-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>${elastic.version}</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>${elastic.version}</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>${elastic.version}</version><!--$NO-MVN-MAN-VER$-->
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Above, please note that we need dependency   spring-boot-starter-data-elasticsearch. In my Elasticsearch cluster, I started Basic security authentication. The password of superuser elastic is set to password. In the application, we have passed   RestHighLevelClient for authentication, so I also   Elastic search rest high level client is introduced.

configuration file

Because the default port address 8080 conflicts with the port of my computer, I use port 9999. In addition, we can also configure the address and port of Elasticsearch. At the same time, we also define the password of super user elastic:

application.properties

server.port = 9999

elasticsearch.url=localhost:9200
elasticsearch.username=elastic
elasticsearch.password=password

document

Employee.java

package com.liuxg.springbootelasticsearchdemo.document;

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;


@Document(indexName = "employees", shards = 1, replicas = 0, refreshInterval = "5s")
public class Employee {

    @Id
    @Field(type = FieldType.Keyword)
    private String id;

    @Field(type = FieldType.Text)
    private String name;

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

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

    public void setName(String name) {
        this.name = name;
    }
}

Above, we defined the name of the index employees. It contains two fields id and name. Their attributes are keyword and text respectively. When we run the Spring Boot application, it will automatically help us produce the employees index in Elasticsearch.

Repository

EmployeeRepository.java

import com.liuxg.springbootelasticsearchdemo.document.Employee;
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import java.util.List;

public interface EmployeeRepository extends ElasticsearchRepository<Employee, String> {
    List<Employee> findAllByName(String name);

    @Query("{\"match\":{\"name\":\"?0\"}}")
    List<Employee> findAllByNameUsingAnnotations(String name);
}

Here, we decide how to access Elasticsearch. Elastic search repository contains many designed methods for us to use.

Service

EmployeeService.java

package com.liuxg.springbootelasticsearchdemo.service;

import com.liuxg.springbootelasticsearchdemo.document.Employee;
import com.liuxg.springbootelasticsearchdemo.repository.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class EmployeeService {

    private final EmployeeRepository repository;

    @Autowired
    public EmployeeService(EmployeeRepository repository) {
        this.repository = repository;
    }

    public void save(final Employee employee) { repository.save(employee); }
    public Employee findById(final String id) { return repository.findById(id).orElse(null); }
    public List<Employee> findByName(final String name) { return repository.findAllByName(name);}

    public List<Employee> getEmployeesByNameUsingAnnotation(String name) {
        return repository.findAllByNameUsingAnnotations(name);
    }

    public void deleteEmployee(String id) {
        repository.deleteById(id);
    }
}

Controller

EmployeeController.java

package com.liuxg.springbootelasticsearchdemo.controller;

import com.liuxg.springbootelasticsearchdemo.document.Employee;
import com.liuxg.springbootelasticsearchdemo.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/employee")
public class EmployeeController {
    private final EmployeeService service;

    @Autowired
    public EmployeeController(EmployeeService service) {
        this.service = service;
    }

    @PostMapping
    public void save(@RequestBody final Employee employee) {
        service.save(employee);
    }

    @GetMapping("/{id}")
    public Employee findById(@PathVariable final String id) {
        return service.findById(id);
    }

    @DeleteMapping("/{id}")
    public boolean deleteById(@PathVariable String id) {
        service.deleteEmployee(id);
        return true;
    }

    @GetMapping("/name/{name}")
    public List<Employee> findAllByName(@PathVariable String name) {
        return service.findByName(name);
    }

    @GetMapping("/name/{name}/annotations")
    public List<Employee> findAllByNameAnnotations(@PathVariable String name) {
        return service.getEmployeesByNameUsingAnnotation(name);
    }
}

Some REST interfaces are defined here to facilitate our access to Elasticsearch.

Configuration

Config.java

package com.liuxg.springbootelasticsearchdemo.configuration;

import lombok.RequiredArgsConstructor;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;

@Configuration
@EnableElasticsearchRepositories(basePackages = "com.liuxg.springbootelasticsearchdemo.repository")
@ComponentScan(basePackages = {"com.liuxg.springbootelasticsearchdemo"})
@RequiredArgsConstructor
public class Config extends AbstractElasticsearchConfiguration {

    @Value("${elasticsearch.url}")
    public String elasticsearchUrl;

    @Value("${elasticsearch.username}")
    public String elasticsearchUsername;

    @Value("${elasticsearch.password}")
    public String elasticsearchPassword;

    @Override
    @Bean
    public RestHighLevelClient elasticsearchClient() {
        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo(elasticsearchUrl)
                .withBasicAuth(elasticsearchUsername, elasticsearchPassword)
                .build();

        return RestClients.create(clientConfiguration).rest();
    }
}

Here, we use the configuration parameters in application.properties to establish a connection with Elasticsearch and return a RestHighLevelClient. Its use can be seen in my previous article“ Elasticsearch: use Spring Boot to create REST APIs to access elasticsearch ”. In this example, it is only used as authentication.

Spring Boot Application

SpringBootElasticsearchDemoApplication.java

package com.liuxg.springbootelasticsearchdemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootElasticsearchDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootElasticsearchDemoApplication.class, args);
    }

}

The structure of the whole code is as follows:

$ tree
.
├── README.md
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── liuxg
    │   │           └── springbootelasticsearchdemo
    │   │               ├── SpringBootElasticsearchDemoApplication.java
    │   │               ├── configuration
    │   │               │   └── Config.java
    │   │               ├── controller
    │   │               │   └── EmployeeController.java
    │   │               ├── document
    │   │               │   └── Employee.java
    │   │               ├── repository
    │   │               │   └── EmployeeRepository.java
    │   │               └── service
    │   │                   └── EmployeeService.java
    │   └── resources
    │       ├── application.properties
    │       ├── static
    │       └── templates
    └── test
        └── java
            └── com
                └── liuxg
                    └── springbootelasticsearchdemo
                        └── SpringBootElasticsearchDemoApplicationTests.java

Test application

We compile the application and run it. In this test, I will use Postman as a test tool for REST interface.

View index created

After the reference is started, it will automatically help us create an index called employees. We can enter the following address in the browser:

http://localhost:9200/_cat/indices

From the above, we can see the employees index that has been created. We can also search in the following ways:

http://localhost:9200/employees/_search

 

From the above returned results, we can see that there is no data in employees. If the results are not displayed in this very nice indented format in your browser, it is recommended that you install it JSON formatter plug-in unit.

Next, we send the request and save the data through the API interface of Spring Boot.

  Above, we pass the interface   http://localhost:9999/api/employee   towards   Elasticsearch sends the following data:

{
    "id": "1",
    "name": "liuxg"
}

The data structure is the format we defined in document. We view the data through the browser again:

http://localhost:9200/employees/_search

We can see the following results:

  From the above, we can see that a data has been written in.

Next, we use the following interface to obtain the data just written:

http://localhost:9999/api/employee/1

It can be seen that our interface works normally.

We can also query a document by searching name:

http://localhost:9999/api/employee/name/liuxg

We can also query through annotations:

http://localhost:9999/api/employee/name/liuxg/annotations

Finally, we can delete the created documents through the API:

http://localhost:9999/api/employee/1

 

  We then query the data of employees through the browser:

From the above, we can see that the previously created file has been successfully deleted.  

  reference resources:

[1]Getting Started With Elasticsearch in Java Spring Boot

[2]Introduction into Spring Data Elasticsearch

Posted by callisto11 on Tue, 19 Oct 2021 19:23:52 -0700