Elasticsearch Java Spring Boot

Introduction-

In this blog, we will learned how to use Elasticsearch with Spring Boot to build a search application. We will created several classes as an example, including ElasticsearchConfig, Book, BookService, BookController, and BookRepository, to demonstrate how to use Elasticsearch with Spring Boot. After this tutorial, you can start building your own search application using Elasticsearch and Spring Boot.

Elasticsearch is a powerful search and analytics engine that can be used to build highly scalable and fault-tolerant applications. In this blog, we will learn how to use Elasticsearch with Spring Boot to build a search application.

First we will Set up a Spring Boot project with Elasticsearch after that we will see how to make connection with elasticsearch. Once connection setupt is done then we will add data then perform queries and searching on Elasticsearch.

Setting up a Spring Boot project with Elasticsearch

First, we need to set up a Spring Boot project with Elasticsearch. To do this, we will use the Spring Initializr to generate a new project with the necessary dependencies.

Go to start.spring.io in your web browser.

1. Enter "codeKatha-Elasticsearch-Example" as the project name (You can enter your own project name).

2. Select "Maven" as the project type.

3. Select the latest stable version of Spring Boot.

4. Add the "Spring Data Elasticsearch" dependency.

5. Click "Generate" to download the project.

Alternatively, you can use the Spring Boot CLI to generate the project using the following command:


spring init --dependencies=elasticsearch codeKatha-Elasticsearch-Example

Adding dependencies in pom.xml


<dependencies>
    <!--Elasticsearch dependencies-->
    <dependency>
        <groupid>org.elasticsearch.client</groupid>
        <artifactid>elasticsearch-rest-high-level-client</artifactid>
        <version>7.16.3</version>
    </dependency>
    
    <dependency>
        <groupid>org.springframework.data</groupid>
        <artifactid>spring-data-elasticsearch</artifactid>
        <version>4.3.3</version>
    </dependency>
    
    <!--Spring Boot dependencies-->
    <dependency>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-web</artifactid>
        <version>2.6.3</version>
    </dependency>
    <!--Other dependencies-->
</dependencies>

Configuration in application.properties

In the application.properties file, you'll need to specify the Elasticsearch connection details. Here's an example configuration:

# Elasticsearch configuration

spring.data.elasticsearch.cluster-nodes=localhost:9200

spring.data.elasticsearch.cluster-name=my-cluster

This configuration specifies that the Elasticsearch cluster is running on the local machine on port 9200, and that the cluster name is "my-cluster".
You can also customize other Elasticsearch settings by adding them to the application.properties file using the spring.data.elasticsearch.* prefix. For example:


# Elasticsearch configuration

spring.data.elasticsearch.cluster-nodes=localhost:9200

spring.data.elasticsearch.cluster-name=my-cluster

spring.data.elasticsearch.properties.http.max_content_length=100mb

This configuration sets the http.max_content_length property to 100mb, which specifies the maximum size of a single request body that Elasticsearch will accept.

Connecting to Elasticsearch

Next, we need to connect to Elasticsearch. 

Create Configuration Class

To do this, we will create a configuration class named ElasticsearchConfig in the com.codekatha.example.elasticsearch.config package.


@Configuration

public class ElasticsearchConfig {



    @Bean

    public RestHighLevelClient elasticsearchClient() {

        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()

                .connectedTo("localhost:9200")

                .build();



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

    }



    @Bean

    public ElasticsearchRestTemplate elasticsearchTemplate() {

        return new ElasticsearchRestTemplate(elasticsearchClient());

    }

}

This class defines two beans: elasticsearchClient and elasticsearchTemplate.

The elasticsearchClient bean creates a connection to Elasticsearch using the RestHighLevelClient class. The elasticsearchTemplate bean provides a high-level API for performing CRUD operations on Elasticsearch.

Adding data to Elasticsearch

Now that we have connected to Elasticsearch, we can add data to Elasticsearch. 

Create Model Class

To do this,we will create a Book class in the com.codekatha.example.elasticsearch.model package.


@Data

@AllArgsConstructor

@NoArgsConstructor

@Builder

@Document(indexName = "books")

public class Book {


    @Id
    
    private String id;

    private String title;

    private String author;

    private String[] categories;

    private String description;

    private Double price;

    private String currency;

    private String image;

    private LocalDate publishedDate;

}

This class represents a book and is annotated with the @Document annotation to indicate that it should be indexed in Elasticsearch. The @Id annotation is used to specify the ID of the document in Elasticsearch.

Create Service Class

Next, we will create a BookService class in the com.codekatha.example.elasticsearch.service package to add data to Elasticsearch.



@Service

public class BookService {



    private final ElasticsearchRestTemplate elasticsearchTemplate;



    @Autowired

    public BookService(ElasticsearchRestTemplate elasticsearchTemplate) {

        this.elasticsearchTemplate = elasticsearchTemplate;

    }



    public void save(Book book) {

        IndexQuery indexQuery = new IndexQueryBuilder()

                .withObject(book)

                .build();

        elasticsearchTemplate.index(indexQuery, RequestOptions.DEFAULT);

    }

}


This class uses the ElasticsearchRestTemplate to add a Book object to Elasticsearch. 

The save method takes a Book object as a parameter, creates an IndexQuery object using the IndexQueryBuilder class, and indexes the Book object in Elasticsearch using the elasticsearchTemplate object.

Performing queries and searching on Elasticsearch

Finally, we can perform queries and searching on Elasticsearch. 

Create Controller Class

To do this, we will create a BookController class in the com.codekatha.example.elasticsearch.controller package.



@RestController

@RequestMapping("/books")

public class BookController {



    private final BookService bookService;



    @Autowired

    public BookController(BookService bookService) {

        this.bookService = bookService;

    }



    @PostMapping

    public void saveBook(@RequestBody Book book) {

        bookService.save(book);

    }



    @GetMapping("/{id}")

    public Book getBookById(@PathVariable String id) {

        return bookService.getById(id);

    }



    @GetMapping

    public List<Book> searchBooks(@RequestParam String query) {

        return bookService.search(query);

    }

}

This class defines three endpoints: /books for saving a Book object, /books/{id} for retrieving a Book object by ID, and /books?query= for searching for Book objects by a query string.

The saveBook method takes a Book object as a parameter and saves it to Elasticsearch using the bookService object.

The getBookById method takes an ID as a parameter and retrieves the corresponding Book object from Elasticsearch using the bookService object.

The searchBooks method takes a query string as a parameter and searches for Book objects in Elasticsearch using the bookService object.

Create Repository Class

Next, we will create a BookRepository interface in the com.codekatha.example.elasticsearch.repository package to define the search method.



public interface BookRepository extends ElasticsearchRepository<Book, String> {



    List<Book> findByTitleOrAuthorOrCategoriesOrDescription(String title, String author, String category, String description);



    @Query("{\"bool\": {\"must\": [{\"query_string\": {\"query\": \"?0\"}}]}}")

    List<Book> search(String query);

}

This code defines an interface called BookRepository that extends ElasticsearchRepository. Elasticsearch is a distributed, open source search and analytics engine used to store and search for data.

The BookRepository interface has two methods defined: findByTitleOrAuthorOrCategoriesOrDescription and search.

The findByTitleOrAuthorOrCategoriesOrDescription method takes four parameters: title, author, category, and description. It searches for books in Elasticsearch that match any of the four parameters provided. The method returns a List<Book> containing all the matching books.

The @Query annotation on the search method specifies a custom Elasticsearch query in JSON format. The query uses the bool query type, which allows for more complex queries by combining multiple queries. In this case, it only has one query: a query_string query type. 

The query string is specified as ?0, which means the first parameter passed to the method will be used as the query string. The search method returns a List<Book> containing all the matching books.

Hope this blog tutorial has been helpful to you. If you have any remaining doubts or suggestions, please feel free to share them in the comments below. We would be glad to receive your feedback.

💛 You can Click Here to connect with us. We will give our best for you.

Comments

Popular Posts on Code Katha

Java Interview Questions for 10 Years Experience

Sql Interview Questions for 10 Years Experience

Spring Boot Interview Questions for 10 Years Experience

Visual Studio Code setup for Java and Spring with GitHub Copilot

Java interview questions - Must to know concepts

Spring Data JPA

Data Structures & Algorithms Tutorial with Coding Interview Questions

Java interview questions for 5 years experience