|
For the latest stable version, please use Spring Data Meilisearch 0.12.0! |
Operations
Spring Data Meilisearch exposes its synchronous, template-style APIs through MeilisearchOperations. The interface
combines document access and search APIs, and provides entry points to instance-level and index-level operations.
Use the MeilisearchOperations interface in application code; see Index and Instance Operations for
instance and index management, Settings for settings, and
Object Mapping for entity conversion.
Entry Point
MeilisearchConfiguration registers one MeilisearchOperations bean with the names meilisearchOperations and
meilisearchTemplate. Inject the interface when you need direct access to Meilisearch-specific operations instead
of the repository abstraction.
getMeilisearchConverter() exposes the configured converter; see Object Mapping for its
mapping and conversion behavior.
@RestController
class MovieController {
private final MeilisearchOperations operations;
MovieController(MeilisearchOperations operations) {
this.operations = operations;
}
@PostMapping("/movies")
Movie save(@RequestBody Movie movie) {
return operations.save(movie);
}
}
Document Operations
DocumentOperations works with one mapped entity type:
-
save(T)andsave(List<T>) -
get(String, Class<T>)andexists(String, Class<?>) -
multiGet(Class<T>, List<String>)for ID-list retrieval -
findAll(Class<T>)andfindAll(Class<T>, Sort)for document listing -
delete(String, Class<?>),delete(T),delete(Class<?>, List<String>),delete(List<T>), anddeleteAll(Class<?>)
save(…) writes through Meilisearch’s
add-or-replace documents API.
The API creates a missing index; replacing an existing document removes fields omitted from the new entity rather
than applying a partial update. Document saves do not automatically apply @Setting metadata.
Both unsorted and sorted findAll(…) use POST /documents/fetch without requesting specific fields.
Meilisearch ignores displayedAttributes for document reads (see its
regression test).
Document listings can therefore return fields excluded from search results; grant documents.get only to callers allowed to read them.
get(…) returns null when the document id is not present. findAll(Class<T>) retrieves all documents in one
document request and holds the result in memory; it is not a Pageable search. A sorted listing also holds the full
result in memory. It counts documents first and then fetches up to that count in one request, so concurrent additions
between the requests may be absent. Sort properties must be configured as Meilisearch sortable attributes, and sorted
document retrieval requires Meilisearch 1.16 or later.
Neither document-list method is bounded by the search-only maxTotalHits setting.
Use multiGet(…) when the ids are already known rather than listing or searching an index:
List<Movie> requested = operations.multiGet(Movie.class, List.of("movie-3", "movie-1", "missing"));
Missing documents are omitted; the remaining results preserve requested order and duplicate ids. The implementation requests document ids in internal batches; callers supply only the ids they want to retrieve. This uses Meilisearch’s native ID-list documents endpoint, which requires Meilisearch 1.14 or later; there is no individual-document lookup fallback for older servers.
Search Operations
SearchOperations provides:
-
long count(Class<?>)for the number of documents in the mapped index. This is a document count, not a query-filtered search count. -
<T, Q extends BaseQuery> SearchHits<T> search(Q, Class<T>)for a single index. -
<T, Q extends BaseQuery> SearchHits<T> multiSearch(List<Q>, Class<T>)for several requests in one non-federated multi-search. -
<T, Q extends BaseQuery> SearchHits<T> multiSearch(List<Q>, MultiSearchFederation, Class<T>)for federated multi-search. -
SearchHits<FacetHit> facetSearch(FacetQuery, Class<?>)for facet search. -
<T> SearchHits<T> similarSearch(SimilarQuery, Class<T>)for similar-document search.
BasicQuery accepts Spring Data Pageable and Sort. The default query page is page 0 with 10 hits; a supplied
Pageable is translated to Meilisearch’s one-based page and hitsPerPage values. Sort properties must be configured
as sortable attributes. Filter expressions likewise require the referenced attributes to be filterable.
BasicQuery query = BasicQuery.builder()
.withQ("Wonder Woman")
.withFilter("genres = Action")
.withPageable(PageRequest.of(0, 20, Sort.by("title")))
.build();
SearchHits<Movie> result = operations.search(query, Movie.class);
List<Movie> movies = result.getSearchHits().stream()
.map(SearchHit::getContent)
.toList();
Multi-Search
Use IndexQuery to override the mapped index uid for an individual request. All results are mapped to the entity type
passed to multiSearch, so the target indexes must return documents compatible with that type.
List<IndexQuery> queries = List.of(
IndexQuery.builder().withQ("Wonder Woman").withIndexUid("movies").build(),
IndexQuery.builder().withQ("Wonder Woman").withIndexUid("comics").build());
SearchHits<Movie> combined = operations.multiSearch(queries, Movie.class);
Non-federated multi-search flattens per-query hits into one SearchHits list in query order; it does not return a
separate SearchHits object for each query or an aggregate total.
Non-federated multi-search supports each query’s Pageable. Federated multi-search instead takes the SDK’s
MultiSearchFederation options for the combined result window. Per-query Pageable settings are not sent in
federated mode; set federation limit and offset instead.
MultiSearchFederation federation = new MultiSearchFederation();
federation.setOffset(0);
federation.setLimit(10);
SearchHits<Movie> federated = operations.multiSearch(queries, federation, Movie.class);
Query Types
Spring Data Meilisearch provides these query value types:
-
BasicQueryfor standard search. -
IndexQueryfor per-index multi-search requests, including federated requests. -
FacetQueryfor facet search. -
SimilarQueryfor similar-document search.
SimilarQuery requires a source document id and the name of an embedder configured for the target index:
SimilarQuery similarQuery = SimilarQuery.builder()
.withDocumentId("movie-1")
.withEmbedder("default")
.build();
SearchHits<Movie> similar = operations.similarSearch(similarQuery, Movie.class);
Search Result Types
Search methods return SearchHits<T>, which exposes the hit list, request execution duration, and total-hit metadata
when the response provides it. Each SearchHit<T> contains the mapped content, Meilisearch processing time and query,
optional facet statistics/distribution, and optional federation metadata.
SearchHits#getTotalHitsRelation() identifies whether getTotalHits() contains a total reported by the search
response:
-
EQUAL_TOmeans Meilisearch reported the total matching-hit count. -
OFFmeans total-hit metadata is unavailable;getTotalHits()then reflects the number of loaded hits and must not be treated as a total for the full result set.
Facet search, similar search, and multi-search results do not provide an aggregate total through this API. For a
single-index search, use total-hit metadata only when its relation is EQUAL_TO.
The maxTotalHits pagination setting limits how many matching hits can be retrieved through paginated search; it
does not necessarily cap the reported total. For example, the current implementation can return 10 hits while
reporting 11 total matches when maxTotalHits is 10. Repository findAll(Pageable) uses search results and their
reported total, while an unpaged repository lookup uses document retrieval. See
Pagination Limits for the pagination setting.
Kotlin Extensions
Spring Data Meilisearch provides Kotlin extension functions for blocking operations that otherwise require an entity
Class argument. Reified type parameters let Kotlin callers omit explicit ::class.java arguments.
import io.vanslog.spring.data.meilisearch.core.*
val movie = operations.get<Movie>("movie-1")
val hits = operations.search<Movie>(query)
val count = operations.count<Movie>()
val index = operations.indexOps<Movie>()
operations.applySettings<Movie>()
These extensions are thin wrappers over the Java contracts. They do not change blocking execution behavior or add reactive or coroutine repository support.