Skip to content

[FEATURE] Add search_pipeline support to _msearch via MultisearchBody #2061

Description

@gndcshv

Is your feature request related to a problem?

The OpenSearch server accepts a per-sub-request search_pipeline on _msearch — placed as a top-level field in the search source body — but the opensearch-java client provides no way to set it.

org.opensearch.client.opensearch.core.msearch.MultisearchBody has no pipeline / search_pipeline field, so applications that want to route individual msearch sub-requests through different search pipelines currently have to bypass the typed builder and construct raw NDJSON by hand.

Concrete use case. A hybrid-search workload where each sub-request needs its own normalization pipeline:

GET /_msearch
{"index":"bulk-search-test"}
{"size":3,"query":{"hybrid":{"queries":[{"match":{"title":"running shoes"}},{"knn":{"embedding":{"vector":[0.85,0.15,0.05],"k":5}}}]}},"search_pipeline":"nlp-pipeline-a"}
{"index":"bulk-search-test"}
{"size":3,"query":{"hybrid":{"queries":[{"match":{"title":"speaker"}},{"knn":{"embedding":{"vector":[0.05,0.15,0.9],"k":5}}}]}},"search_pipeline":"nlp-pipeline-b"}
{"index":"bulk-search-test"}
{"size":3,"query":{"term":{"category":"footwear"}}}

This request works end-to-end when sent as raw NDJSON via against a 3.7 cluster, but there is no way to express it through MsearchRequest.Builder today — MultisearchBody.Builder has no searchPipeline(...) method.

What solution would you like?

Add a searchPipeline field to MultisearchBody (JSON key search_pipeline), matching the accessor name used by SearchRequest#searchPipeline for single _search. This lets callers write:

MsearchRequest req = MsearchRequest.of(m -> m
    .searches(s -> s
        .header(h -> h.index("bulk-search-test"))
        .body(b -> b
            .query(/* ... */)
            .searchPipeline("nlp-pipeline-a")   // NEW
        )
    )
    .searches(s -> s
        .header(h -> h.index("bulk-search-test"))
        .body(b -> b
            .query(/* ... */)
            .searchPipeline("nlp-pipeline-b")   // NEW
        )
    )
);

The emitted NDJSON should match the working payload above (each search_pipeline on its body line, not the header line).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions