Integrating Elasticsearch with Spring Boot for Full‑Text Search in a Microservice Architecture

This tutorial demonstrates how to integrate Elasticsearch into a Spring Boot microservice, covering component selection, Maven configuration, client setup, index creation, data insertion, complex query execution, synchronization of question data, and front‑end search handling, all illustrated with complete Java code examples.

Wukong Talks Architecture
Wukong Talks Architecture
Wukong Talks Architecture
Integrating Elasticsearch with Spring Boot for Full‑Text Search in a Microservice Architecture

Introduction

The article builds on a previous discussion of Elasticsearch full‑text search principles and shows how to integrate Elasticsearch into a Spring Boot application and a Spring Cloud microservice project to achieve full‑text search for a large question‑answer dataset.

Elasticsearch Component Library

Elasticsearch 7.4.2 is used with the official Elasticsearch Rest High Level Client. The official documentation URL is

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html

. Both the high‑level and low‑level clients exist, but the high‑level client is preferred for its richer features.

Integrating the Search Service

1.1 Add Search Service Module

A new module passjava-search is created using Spring Initializr with the Spring Web dependency.

1.2 Configure Maven Dependencies

Add the following dependency to passjava-search/pom.xml:

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.4.2</version>
</dependency>

Set the Elasticsearch version property to 7.4.2 to avoid version mismatches.

<properties>
    <elasticsearch.version>7.4.2</elasticsearch.version>
</properties>

Include the common module dependency:

<dependency>
    <groupId>com.jackson0714.passjava</groupId>
    <artifactId>passjava-common</artifactId>
    <version>0.0.1‑SNAPSHOT</version>
</dependency>

1.3 Register Service with Nacos

Add the following properties to src/main/resources/application.properties:

spring.application.name=passjava-search
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=passjava-search

Annotate the main class with @EnableDiscoveryClient and exclude the datasource auto‑configuration.

@EnableDiscoveryClient
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class PassjavaSearchApplication {
    public static void main(String[] args) {
        SpringApplication.run(PassjavaSearchApplication.class, args);
    }
}

1.4 Add Elasticsearch Configuration Class

Create PassJavaElasticsearchConfig.java to provide a RestHighLevelClient bean:

package com.jackson0714.passjava.search.config;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class PassJavaElasticsearchConfig {
    @Bean
    public RestHighLevelClient restHighLevelClient() {
        return new RestHighLevelClient(
            RestClient.builder(new HttpHost("192.168.56.10", 9200, "http")));
    }
}

1.5 Test Client Auto‑Loading

In PassjavaSearchApplicationTests inject the client and print it:

@SpringBootTest
class PassjavaSearchApplicationTests {
    @Qualifier("restHighLevelClient")
    @Autowired
    private RestHighLevelClient client;

    @Test
    void contextLoads() {
        System.out.println(client);
    }
}

1.6 Simple Data Insertion Test

Insert a User document into the users index:

IndexRequest request = new IndexRequest("users");
request.id("1");
User user = new User();
user.setUserName("PassJava");
user.setAge("18");
user.setGender("Man");
String jsonString = JSON.toJSONString(user);
request.source(jsonString, XContentType.JSON);
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
System.out.println(response);

Verify insertion with GET users/_search and observe the returned JSON fields.

1.7 Complex Query Example

Demonstrates a search on the bank index with address matching, age aggregation, and average salary aggregation. The request is built with SearchRequest, SearchSourceBuilder, and appropriate aggregations, then executed and parsed.

Synchronizing ES Data

3.1 Define Search Model

The question index stores title and answer fields (both analyzed with ik_smart), plus id and typeName.

"title": {"type": "text", "analyzer": "ik_smart"},
"answer": {"type": "text", "analyzer": "ik_smart"}

3.2 Create Index

PUT question
{
  "mappings": {
    "properties": {
      "id": {"type": "long"},
      "title": {"type": "text", "analyzer": "ik_smart"},
      "answer": {"type": "text", "analyzer": "ik_smart"},
      "typeName": {"type": "keyword"}
    }
  }
}

3.3 Define ES Model Class

@Data
public class QuestionEsModel {
    private Long id;
    private String title;
    private String answer;
    private String typeName;
}

3.4 Save Data to ES

When a question is saved to MySQL, the service copies properties to QuestionEsModel (using BeanUtils.copyProperties) and calls the passjava-search service to index the document.

searchFeignService.saveQuestion(esModel);

Querying ES Data

4.1 Request Parameters

Three parameters are defined: keyword (full‑text match), id (exact match), and pageNum (pagination).

@Data
public class SearchParam {
    private String keyword;
    private String id;
    private Integer pageNum;
}

4.2 Response Structure

@Data
public class SearchQuestionResponse {
    private List<QuestionEsModel> questionList;
    private Integer pageNum;
    private Long total;
    private Integer totalPages;
}

4.3 Assemble Search Request

Create a SearchRequest for the question index, add a multiMatchQuery on title, answer, and typeName, set from and size for pagination, then execute.

SearchRequest request = new SearchRequest("question");
SearchSourceBuilder builder = new SearchSourceBuilder();
BoolQueryBuilder bool = QueryBuilders.boolQuery();
if (param.getKeyword() != null) {
    bool.must(QueryBuilders.multiMatchQuery(param.getKeyword(), "title", "answer", "typeName"));
}
if (param.getId() != null) {
    bool.filter(QueryBuilders.termQuery("id", param.getId()));
}
builder.query(bool);
builder.from((param.getPageNum() - 1) * 5);
builder.size(5);
request.source(builder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);

4.4 Format Search Results

Extract hits, deserialize each hit into QuestionEsModel, and populate pagination fields.

SearchHits hits = response.getHits();
SearchHit[] searchHits = hits.getHits();
List<QuestionEsModel> list = new ArrayList<>();
for (SearchHit hit : searchHits) {
    QuestionEsModel model = JSON.parseObject(hit.getSourceAsString(), QuestionEsModel.class);
    list.add(model);
}
SearchQuestionResponse result = new SearchQuestionResponse();
result.setQuestionList(list);
result.setPageNum(param.getPageNum());
result.setTotal(hits.getTotalHits().value);
result.setTotalPages((int) Math.ceil((double) hits.getTotalHits().value / 5));

Conclusion

The article provides a step‑by‑step guide on integrating Elasticsearch with a Spring Boot microservice, covering client configuration, index creation, data synchronization, and query implementation, enabling efficient full‑text search for large question‑answer datasets.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

javaMicroservicesElasticsearchSpring BootFull‑Text Search
Wukong Talks Architecture
Written by

Wukong Talks Architecture

Explaining distributed systems and architecture through stories. Author of the "JVM Performance Tuning in Practice" column, open-source author of "Spring Cloud in Practice PassJava", and independently developed a PMP practice quiz mini-program.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.