Integrating Elasticsearch with Spring Boot for Book Search: A Step‑by‑Step Guide
This article explains why MySQL LIKE queries are inefficient for search, introduces Elasticsearch as a high‑performance alternative, and provides a complete Spring Boot integration tutorial—including version compatibility, Maven dependencies, Java configuration, entity mapping, repository interfaces, service and controller code, and testing steps—to implement CRUD‑style full‑text search for a book catalog.
When a system needs a search feature, using MySQL LIKE queries can degrade performance, so the article adopts Elasticsearch for in‑site search.
Spring Boot and Elasticsearch version compatibility
Elasticsearch 7.x no longer supports custom types; it uses the default type _doc and each index can have only one type. To avoid mismatched versions, the article recommends using matching releases: Spring Boot 2.3.7.RELEASE with Elasticsearch 7.6.2 (see the compatibility table image).
Create Spring Boot project and add Elasticsearch dependencies
Spring Boot version used: 2.3.7.RELEASE
Corresponding Elasticsearch version: 7.6.2
Add the Spring Data Elasticsearch starter dependency (Spring‑Data prefix groups Elasticsearch under the data umbrella):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>If JPA is also needed, add the JPA starter:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>Java configuration for Elasticsearch
Create a configuration class RestClientConfig that extends AbstractElasticsearchConfiguration and provides a RestHighLevelClient bean:
/**
* ElasticSearch client configuration
*
* @author geng
*/
@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:9200")
.build();
return RestClients.create(clientConfiguration).rest();
}
}Note: Starting with Elasticsearch 7, TransportClient is deprecated and will be removed in 8.0. Spring Data Elasticsearch still supports it for older versions, but the High Level Rest Client is recommended.
CRUD operations like a regular database
Define a Book entity with Spring Data Elasticsearch annotations:
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.util.Date;
/**
* @author geng
*/
@Data
@Document(indexName = "book", createIndex = true)
public class Book {
@Id
@Field(type = FieldType.Text)
private String id;
@Field(analyzer = "ik_max_word")
private String title;
@Field(analyzer = "ik_max_word")
private String author;
@Field(type = FieldType.Double)
private Double price;
@Field(type = FieldType.Date, format = DateFormat.basic_date_time)
private Date createTime;
@Field(type = FieldType.Date, format = DateFormat.basic_date_time)
private Date updateTime;
}@Document defines the index name and creation policy.
@Id maps to Elasticsearch’s _id field.
@Field specifies field type, analyzer, and date format.
Refer to the official docs for more annotations.
Elasticsearch Repositories
Create an interface ESBookRepository extending ElasticsearchRepository:
import com.gyb.elasticsearch.demo.entity.es.Book;
import org.springframework.data.elasticsearch.annotations.Highlight;
import org.springframework.data.elasticsearch.annotations.HighlightField;
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import java.util.List;
/**
* ES Book repository
*
* @author geng
*/
public interface ESBookRepository extends ElasticsearchRepository<Book, String> {
List<Book> findByTitleOrAuthor(String title, String author);
@Highlight(fields = {
@HighlightField(name = "title"),
@HighlightField(name = "author")
})
@Query("{\"match\":{\"title\":\"?0\"}}")
SearchHits<Book> find(String keyword);
}Method names are parsed into Elasticsearch queries automatically; custom queries can be defined with @Query and result highlighting with @Highlight.
Service layer
/**
* @author geng
*/
@Slf4j
@Service
public class BookService {
private final BookRepository bookRepository;
private final ESBookRepository esBookRepository;
private final TransactionTemplate transactionTemplate;
public BookService(BookRepository bookRepository, ESBookRepository esBookRepository, TransactionTemplate transactionTemplate) {
this.bookRepository = bookRepository;
this.esBookRepository = esBookRepository;
this.transactionTemplate = transactionTemplate;
}
public void addBook(Book book) {
final Book saveBook = transactionTemplate.execute(status -> bookRepository.save(book));
final com.gyb.elasticsearch.demo.entity.es.Book esBook = new com.gyb.elasticsearch.demo.entity.es.Book();
assert saveBook != null;
BeanUtils.copyProperties(saveBook, esBook);
esBook.setId(saveBook.getId() + "");
try {
esBookRepository.save(esBook);
} catch (Exception e) {
log.error(String.format("保存ES错误!%s", e.getMessage()));
}
}
public List<com.gyb.elasticsearch.demo.entity.es.Book> searchBook(String keyword) {
return esBookRepository.findByTitleOrAuthor(keyword, keyword);
}
public SearchHits<com.gyb.elasticsearch.demo.entity.es.Book> searchBook1(String keyword) {
return esBookRepository.find(keyword);
}
}Controller layer
/**
* @author geng
*/
@RestController
public class BookController {
private final BookService bookService;
public BookController(BookService bookService) {
this.bookService = bookService;
}
@PostMapping("/book")
public Map<String, String> addBook(@RequestBody Book book) {
bookService.addBook(book);
Map<String, String> map = new HashMap<>();
map.put("msg", "ok");
return map;
}
@GetMapping("/book/search")
public SearchHits<com.gyb.elasticsearch.demo.entity.es.Book> search(String key) {
return bookService.searchBook1(key);
}
}Testing the implementation
1. Start Elasticsearch service
No manual index creation is required; Spring Boot will create the book index on startup.
2. Start the Spring Boot application
3. Add test data via the /book endpoint
curl -H "Content-Type:application/json" -XPOST http://localhost:8080/book -d {
"id":"1",
"title":"富婆通讯录",
"author":"耿小李",
"price":9999.9,
"createTime":"2020-12-21 12:00:00"
}4. Search data
Open a browser and visit http://localhost:8080/book/search?key=富婆 to see the search results.
For further details, refer to the official Spring Data Elasticsearch documentation and the GitHub repository:
https://docs.spring.io/spring-data/elasticsearch/docs/4.1.2/reference/html/#preface
https://github.com/cloudgyb/es-spring-boot
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
