Full-Text Search with Spring Data Elasticsearch on Spring Boot 4
Spring Data Elasticsearch's ElasticsearchRepository looks exactly like JpaRepository — derived query methods, @Id, the same muscle memory. That similarity hides the one decision that actually matters in Elasticsearch: how each field is mapped. Map a field "text" and it's tokenized, stemmed and fuzzy-matchable; map it "keyword" and it's an exact, unanalyzed string good for filtering, sorting and aggregating. Pick wrong and nothing throws an error — the field just quietly stops doing what you expect. This post builds a small product-search service on Spring Boot 4.1 and Elasticsearch 9.4 — a repository for the simple lookups, and the query DSL for everything a repository method can't express: multi-field relevance scoring with per-field boosting, typo-tolerant fuzzy matching, a price filter that narrows results without touching their rank, and a terms aggregation for category facet counts. Versions used in this post. Spring Boot 4.1.1 · Spring Data Elasticsearch 6.1.1 · elasticsearch-java client 9.4.5 · Elasticsearch server 9.4.8 · JDK 25 (Temurin) · Testcontainers 2.0.5 (testcontainers-elasticsearch). The server version is pinned to match the client's minor version — confirmed via mvn dependency:tree rather than assumed, after discovering elsewhere in this series that a mismatched tag can be silently broken upstream.