Spring Boot with Elasticsearch: Full-Text Search Integration


Elasticsearch is a powerful, distributed search and analytics engine designed for horizontal scalability and real-time data access. It’s widely used to implement full-text search, log analysis, and other search-based use cases. Integrating Elasticsearch with Spring Boot allows developers to build fast and scalable applications that can handle large datasets efficiently while providing advanced search capabilities.

What is Full-Text Search?

Full-text search allows users to search through a vast body of text (like documents, articles, or product catalogs) and retrieve results based on relevance. Unlike simple keyword searches, full-text search can rank documents based on how closely they match the search query. Features such as fuzzy matching, wildcard searches, and filtering can enhance the search experience.

Why Integrate Elasticsearch with Spring Boot?

  1. Scalability: Elasticsearch can handle large amounts of data and search queries efficiently, making it perfect for applications that require fast search capabilities.
  2. Flexibility: Elasticsearch offers advanced querying capabilities such as fuzzy search, autocomplete, and geospatial search, which are challenging to implement in traditional relational databases.
  3. Real-Time Data Access: Elasticsearch supports real-time indexing and search, ensuring that the data is available immediately after being added or modified.

What You Will Learn:

  • How to set up Elasticsearch with Spring Boot
  • How to create an entity and repository for Elasticsearch integration
  • Implementing full-text search using Elasticsearch’s powerful querying features
  • Exposing the search functionality via RESTful APIs

Step 1: Setting Up Elasticsearch

Before we start coding, we need to make sure Elasticsearch is running. You can either download and run Elasticsearch locally or use a cloud-based instance.

Running Elasticsearch Locally with Docker
The easiest way to get Elasticsearch running is by using Docker. Here’s how to do it:

  1. Make sure you have Docker installed.
  2. Run the following command in your terminal:
    docker run -d -p 9200:9200 -p 9300:9300 --name elasticsearch docker.elastic.co/elasticsearch/elasticsearch:8.0.0
    
    • This command will start an Elasticsearch instance on http://localhost:9200.

    Verify Elasticsearch is Running
    Visit http://localhost:9200 in your browser or use curl:

    curl http://localhost:9200
    

    You should see a JSON response containing details about your Elasticsearch instance.


    Step 2: Setting Up Your Spring Boot Project

    Now that we have Elasticsearch running, let’s set up a Spring Boot application.

    1. Create a Spring Boot Application
      If you don’t have an existing Spring Boot application, you can quickly generate one from Spring Initializr.
      Add the following dependencies:

      • Spring Web: For creating RESTful APIs.
      • Spring Data Elasticsearch: For integrating Spring Boot with Elasticsearch.
      • Spring Boot DevTools (optional): For automatic restarts during development.
    2. Add Maven Dependencies
      Open your pom.xml and add the following dependency for Elasticsearch:
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
    

    This dependency will include Spring Data Elasticsearch and all necessary libraries.


    Step 3: Configure Elasticsearch in Spring Boot

    Next, we need to configure the connection between Spring Boot and Elasticsearch.

    In src/main/resources/application.properties, add the following configuration:

    # Elasticsearch settings
       spring.elasticsearch.rest.uris=http://localhost:9200
       spring.elasticsearch.rest.read-timeout=5s
       spring.elasticsearch.rest.connection-timeout=3s
    

    These settings define the Elasticsearch server URL and connection timeouts. You can adjust the URLs based on your setup (local or cloud).


    Step 4: Define an Elasticsearch Entity

    In this step, we’ll create an entity class that represents the data we will store in Elasticsearch. For this example, let’s create a Product entity that we will index and search.

    Create a new class Product.java in the model package:

    import org.springframework.data.annotation.Id;
    import org.springframework.data.elasticsearch.annotations.Document;
    
    @Document(indexName = "products")
    public class Product {
        
        @Id
        private String id;
        private String name;
        private String description;
        private double price;
    
        // Getters and setters
    }
    
    • The @Document annotation indicates that this class is an Elasticsearch document.
    • @Id defines the field that will act as the primary key for the document.
    • The indexName specifies the name of the Elasticsearch index (products).

    Step 5: Create a Repository for Elasticsearch

    Spring Data Elasticsearch provides an abstraction layer to interact with Elasticsearch. We will create a repository interface to perform operations like saving, retrieving, and searching the Product entities.

    Create a new interface ProductRepository.java in the repository package:

    import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
    
    public interface ProductRepository extends ElasticsearchRepository<Product, String> {
        List findByNameContaining(String name);
    }
    
    • ElasticsearchRepository provides basic CRUD operations.
    • The custom method findByNameContaining allows us to search for products by name using full-text search.

    Step 6: Implement the Search Functionality
    Now, let’s implement the service layer that will handle the search logic. We’ll use the repository to search for products by name.

    Create a new service class ProductService.java in the service package:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    @Service
    public class ProductService {
    
        @Autowired
        private ProductRepository productRepository;
    
        public List searchProducts(String query) {
            return productRepository.findByNameContaining(query);
        }
    }
    • The method searchProducts uses the findByNameContaining method from the repository to perform a full-text search on the product name.

    Step 7: Expose the Search API

    Finally, we will expose the search functionality through a REST API using Spring MVC. This will allow us to query products by name via HTTP requests.

    Create a new controller class ProductController.java in the controller package:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.List;
    
    @RestController
    public class ProductController {
    
        @Autowired
        private ProductService productService;
    
        @GetMapping("/search")
        public List search(@RequestParam String query) {
            return productService.searchProducts(query);
        }
    }
    
    • The /search endpoint accepts a query parameter (query) and returns a list of products that match the search term.

    Step 8: Run the Application

    With everything set up, it’s time to run the application:

    1. Start your Spring Boot application by running the main class Application.java.
    2. Elasticsearch should be running on http://localhost:9200.

    Now, you can test the search functionality by sending HTTP GET requests:

    http://localhost:8080/search?query=laptop
    

    You should see a JSON response with products that contain the word “laptop” in their name.


    Step 9: Advanced Search Features

    Elasticsearch supports a variety of advanced features that you can integrate into your Spring Boot application:

    • Fuzzy Search: Find documents with spelling variations using the ~ operator.
    • Wildcard Search: Use * for flexible search terms, e.g., name: "laptop*".
    • Faceted Search: Aggregate data to provide stats or filter by categories.
    • Boosting: Increase the relevance of specific fields using boost.

    You can extend your ProductRepository with more advanced queries using the @Query annotation or custom Elasticsearch queries.


    Conclusion

    In this tutorial, we learned how to integrate Spring Boot with Elasticsearch to build a full-text search feature. We set up Elasticsearch, created a Spring Boot application with a Product entity, and implemented full-text search through a REST API.

    Elasticsearch provides a robust, scalable solution for handling large datasets and performing advanced search queries, making it perfect for applications that need fast and relevant search capabilities.