Does a utility function exist for converting SearchRequest into a RequestItem for elasticsearch-java?

Does a utility function exist for converting a SearchRequest into a RequestItem for performing multi search requests with the elasticsearch-java.

The Java highlevel client allowed to create a multisearch request using a list of existing SearchRequest Queries. The elasticsearch-java SDK requeries a list of SearchRequestItem values. I could not find a utility function. I rolled my own by using autocomplete in the IDE, going over all letters of the alphabet. This by itself is error prone. Also later additions by Elastic might go unnoticed.

Is there a utility function or is my current approach as shown below correct?

 public <T> @NotNull MsearchResponse<T> executeRequests(final @NotNull List<SearchRequest> requests, final @NotNull Class<T> clazz) throws IOException {
        if (requests.isEmpty()) {
            throw new IllegalArgumentException("requests must not be empty");
        }

        return client.msearch(multiSearchRequestBuilder -> multiSearchRequestBuilder.searches(toRequestItems(requests)), clazz);
    }

    private @NotNull List<RequestItem> toRequestItems(final @NotNull List<SearchRequest> requests) {
        return requests.stream().map(this::toRequestItem).toList();
    }

    private @NotNull RequestItem toRequestItem(final @NotNull SearchRequest searchRequest) {
        //REMARK: fragile, additions by elastic will go unnoticed.
        return new RequestItem.Builder()
                .header(headerBuilder -> headerBuilder
                        .allowNoIndices(searchRequest.allowNoIndices())
                        .allowPartialSearchResults(searchRequest.allowPartialSearchResults())
                        .ccsMinimizeRoundtrips(searchRequest.ccsMinimizeRoundtrips())
                        .expandWildcards(searchRequest.expandWildcards())
                        .ignoreThrottled(searchRequest.ignoreThrottled())
                        .ignoreUnavailable(searchRequest.ignoreUnavailable())
                        .index(searchRequest.index())
                        .preference(searchRequest.preference())
                        .requestCache(searchRequest.requestCache())
                        .routing(searchRequest.routing())
                        .searchType(searchRequest.searchType())
                )
                .body(bodyBuilder -> bodyBuilder
                        .aggregations(searchRequest.aggregations())
                        .collapse(searchRequest.collapse())
                        .docvalueFields(searchRequest.docvalueFields())
                        .explain(searchRequest.explain())
                        .ext(searchRequest.ext())
                        .fields(searchRequest.fields())
                        .from(searchRequest.from())
                        .highlight(searchRequest.highlight())
                        .indicesBoost(searchRequest.indicesBoost())
                        .knn(searchRequest.knn())
                        .minScore(searchRequest.minScore())
                        .pit(searchRequest.pit())
                        .postFilter(searchRequest.postFilter())
                        .profile(searchRequest.profile())
                        .query(searchRequest.query())
                        .rescore(searchRequest.rescore())
                        .scriptFields(searchRequest.scriptFields())
                        .searchAfter(searchRequest.searchAfter())
                        .seqNoPrimaryTerm(searchRequest.seqNoPrimaryTerm())
                        .size(searchRequest.size())
                        .sort(searchRequest.sort())
                        .source(searchRequest.source())
                        .stats(searchRequest.stats())
                        .storedFields(searchRequest.storedFields())
                        .suggest(searchRequest.suggest())
                        .terminateAfter(searchRequest.terminateAfter())
                        .trackScores(searchRequest.trackScores())
                        .trackTotalHits(searchRequest.trackTotalHits())
                        .timeout(searchRequest.timeout())
                        .version(searchRequest.version())
                )
                .build();
    }

Hey! Unfortunately no, the Java High Level Client used to have more utility methods and syntactic sugar than the new Java Client - this is simply because it existed for a longer time and the people working on it managed to add these kind of enhancements. We'll keep working on the new one :slight_smile:

In the meantime, I'd use a mapper (such as MapStruct or ModelMapper) since the fields are the same.