Master Spring Boot 2.3 with Elasticsearch 7: Full Integration Guide
This tutorial walks through configuring Spring Boot 2.3.10 with Elasticsearch 7.8, defining Maven dependencies, setting up application properties, creating a searchable Product model, implementing a repository with derived query methods and custom @Query annotations, and testing CRUD and advanced search operations using both repository and RestTemplate approaches.
Environment: Spring Boot 2.3.10.RELEASE + Elasticsearch 7.8.0
Related Dependencies and Application Configuration
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> spring:
elasticsearch:
rest:
uris:
- http://localhost:9201
logging:
level:
com.pack: debug
org.springframework.data.elasticsearch.core: debugData Model Definition
@Document(createIndex = true, indexName = "products", shards = 3, replicas = 1)
public class Product {
@Id
private Long id;
@Field(analyzer = "ik_max_word", type = FieldType.Text)
private String title;
@Field(type = FieldType.Keyword)
private String category;
@Field(type = FieldType.Double)
private Double price;
@Field(type = FieldType.Keyword, index = false)
private String images;
@Override
public String toString() {
return "Product [id=" + id + ", title=" + title + ", category=" + category + ", price=" + price + ", images=" + images + "]";
}
}ProductRepository
By extending ElasticsearchRepository, the repository gains the same method‑generation capabilities as Spring Data JPA.
public interface ProductRepository extends ElasticsearchRepository<Product, Long> {
}Derived query methods such as findByTitle are supported, and the following keywords can be used in method names:
Supported Keywords
Return Types
List<T>
Stream<T>
SearchHits<T>
List<SearchHit<T>>
Stream<SearchHit<T>>
SearchPage<T>
Custom queries can be defined with the @Query annotation, and result highlighting is available via @Highlight and @HighlightField:
public interface ProductRepository extends ElasticsearchRepository<Product, Long> {
List<Product> findByTitle(String title);
@Query("{\"fuzzy\": {\"title\": \"?0\"}}")
Page<Product> findByTitle(String title, Pageable pageable);
@Query("{\"match\": {\"category\": \"?0\"}}")
Page<Product> findByCategory(String category, Pageable pageable);
@Highlight(fields = {@HighlightField(name = "title"), @HighlightField(name = "category")})
List<SearchHit<Product>> findByTitleOrCategory(String title, String category, Pageable pageable);
}Alternatively, ElasticsearchRestTemplate can be used for more flexible queries.
Tests
@Resource
private ProductRepository productRepository;
@Resource
private ElasticsearchRestTemplate elasticTemplate;
@Test
public void testCreate() {
Product product = new Product();
product.setId(3L);
product.setCategory("配件");
product.setPrice(299.5d);
product.setImages("http://www.pack.com/memory.jpg");
product.setTitle("很牛逼的内存条");
productRepository.save(product);
}
@Test
public void testQuery() {
Product product = productRepository.findById(1L).orElse(null);
System.out.println(product);
}
@Test
public void testFindAll() {
Pageable pageable = PageRequest.of(1, 2);
Page<Product> page = productRepository.findAll(pageable);
System.out.println(page.getTotalPages() + "
" + page.getContent());
}
@Test
public void testTermSearch() {
for (Product p : productRepository.findByTitle("Java从入门到精通")) {
System.out.println(p);
}
}
@Test
public void testFindByTitle() {
Pageable pageable = PageRequest.of(0, 2);
Page<Product> page = productRepository.findByTitle("Java", pageable);
System.out.println(page.getTotalPages() + "
" + page.getContent());
}
@Test
public void testFindByCategory() {
Pageable pageable = PageRequest.of(0, 2);
Page<Product> page = productRepository.findByCategory("书籍", pageable);
System.out.println(page.getTotalPages() + "
" + page.getContent());
}
@Test
public void testCriteriaQuery() {
Criteria criteria = new Criteria("price").greaterThan(50).lessThan(80);
Query query = new CriteriaQuery(criteria);
SearchHits<Product> hits = elasticTemplate.search(query, Product.class, IndexCoordinates.of("products"));
for (SearchHit<Product> hit : hits) {
System.out.println(hit);
}
}
@Test
public void testStringQuery() {
Query query = new StringQuery("{ \"match\": { \"category\": { \"query\": \"配件\" } } }");
SearchHits<Product> hits = elasticTemplate.search(query, Product.class);
for (SearchHit<Product> hit : hits) {
System.out.println(hit);
}
}
@Test
public void testStringQueryFuzzy() {
Query query = new StringQuery("{ \"fuzzy\":{\"title\":{\"value\":\"Java\"}} }");
HighlightBuilder highBuilder = new HighlightBuilder()
.preTags("<font color='red'>")
.postTags("</font>")
.field("title");
HighlightQuery highlightQuery = new HighlightQuery(highBuilder);
query.setHighlightQuery(highlightQuery);
SearchHits<Product> hits = elasticTemplate.search(query, Product.class);
for (SearchHit<Product> hit : hits) {
System.out.println(hit + "
" + hit.getHighlightField("title"));
}
}When the application starts, the index is created automatically.
For visual inspection, the Chrome extension ElasticSearch Head provides a convenient UI.
The following screenshot shows a sample cluster setup.
All steps above demonstrate a complete end‑to‑end integration of Spring Boot with Elasticsearch for backend search capabilities.
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.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
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.
