Building Hybrid Search in OpenSearch: BM25, k-NN, Filters, and Reranking
Content reflects the state as of June 2026. AI tooling and model capabilities in this area change frequently.
Hybrid search fails when teams treat it as “BM25 plus vectors.” Production hybrid search is a retrieval pipeline: lexical candidates, semantic candidates, hard filters, score normalization, fusion, reranking, evaluation, and operational telemetry. OpenSearch can run that pipeline, but it will not design the relevance model for you.
Short Version
OpenSearch is a strong platform for hybrid search when lexical relevance, vector recall, structured filters, relevance debugging, and operational search tooling all matter. The core design is not one query. It is a candidate pipeline with explicit constraints, rank fusion, reranking, and feedback loops.
Use BM25 for exact terms, phrases, identifiers, and field-aware relevance. Use k-NN for semantic recall. Apply hard filters for tenant, entitlement, deletion state, region, compliance, inventory, and other non-negotiable constraints. Fuse or normalize candidate sets carefully, then rerank a bounded set when needed.
OpenSearch hybrid search features and query syntax are version-specific — the normalization-processor search pipeline (the mechanism most of this post assumes) is the current, generally-available way to fuse BM25 and k-NN scores, but confirm exact syntax against the deployed OpenSearch version before writing pipeline definitions, since hybrid search has picked up new configuration options across recent releases.
Situation
Organizations adopt OpenSearch hybrid search when users need both exact words and semantic meaning. Support search needs error codes and paraphrases. Product search needs SKUs and intent. Internal knowledge search needs names, acronyms, and conceptual matching.
The business asks for “better search.” The platform team has to define what better means.
The Problem
BM25 and vector similarity produce different kinds of evidence.
BM25 is strong when the user’s query and the document share terms. It handles exact identifiers, rare words, field boosts, analyzers, and phrase behavior. Dense vector search is strong when the user’s query and document mean similar things with different words.
Combining them creates production questions:
- Which filters are hard constraints versus ranking signals?
- How many candidates come from each retrieval path?
- How are scores normalized?
- Does an exact identifier match beat a semantic paraphrase?
- Where does reranking happen?
- How are bad results debugged?
- How does the team roll back a relevance change?
Without answers, hybrid search becomes an opaque scoring soup.
Core Technical Explanation
A production hybrid pipeline separates stages:
flowchart TD
Query[user query] --> Parse[query parsing and intent]
Parse --> Lex[BM25 candidate query]
Parse --> Vec[k-NN candidate query]
Parse --> Filter[hard metadata filters]
Filter --> Lex
Filter --> Vec
Lex --> Fusion[score normalization or rank fusion]
Vec --> Fusion
Fusion --> Rerank[bounded reranking]
Rerank --> Explain[logs and relevance debugging]
Explain --> Results[ranked results]
The lexical path should know which fields matter. A title match may be stronger than a body match. A SKU field should not use the same analyzer as prose. Synonyms and stemming should be tested, not assumed.
The vector path should know which embedding field it searches. Title embeddings, body embeddings, and support-ticket embeddings may have different behavior. A single generic embedding field may be acceptable for a first version but makes debugging harder.
Filters should be shared across both paths. If BM25 searches one corpus and k-NN searches another, fusion results become inconsistent and security risk rises.
Fusion can be score-based or rank-based. Raw BM25 scores and vector scores are not naturally comparable — OpenSearch’s documented approach is the normalization-processor pipeline, which applies a normalization technique (commonly min-max) to bring both score families onto a comparable scale, then combines them with a weighted technique such as arithmetic mean. Normalization, rank fusion, or a reranker should be chosen deliberately, not left at whatever default a tutorial used.
In Practice
Operate hybrid search like a release pipeline:
Define query classes. Exact identifier lookup, troubleshooting question, product discovery, known-title lookup, and broad semantic exploration should not be tuned from one average metric.
Create relevance sets. Keep a protected set of queries with expected good, acceptable, and bad results. Include tenant-filtered negative cases.
Log candidate stages. Store which path produced each candidate, the rank from each path, filter context, final rank, and reranker features. Do not log sensitive body text unless policy allows it.
Bound reranking. Rerank the top candidates, not the whole index. The reranker should improve final ordering without hiding broken retrieval.
Separate hard constraints. Tenant, region, deletion state, compliance, entitlement, and inventory availability are not soft boosts.
Use aliases for releases. Build replacement indexes for mapping or embedding changes, compare results, then switch aliases when validation passes.
Where It Breaks
| Failure mode | Symptom | Fix |
|---|---|---|
| Raw score mixing | BM25 or vector path dominates unpredictably | Normalize or use rank-based fusion |
| Candidate pool too small | Reranker cannot recover missing documents | Increase lexical or vector candidate size |
| Filters differ by path | Inconsistent or unauthorized results | Centralize filter construction |
| Reranker hides retrieval bugs | Final results look okay until tail queries fail | Log pre-rerank candidates |
| Analyzer breaks identifiers | SKUs or error codes stop matching | Use keyword fields and query-set tests |
| Embedding model changes silently | Relevance shifts without review | Version vectors and release indexes |
Security and Tenancy Notes
Hybrid search doubles the chance of filter mistakes because there are multiple retrieval paths. The same security constraints must apply to BM25, k-NN, fusion, reranking, and fallback.
If reranking calls an external model, retrieved snippets may leave the OpenSearch boundary. That must be reviewed as data processing, not only relevance engineering — whoever owns the data-processing agreement with that model provider needs to sign off, since this is a contractual and compliance question, not a configuration flag.
Cost Notes
Hybrid search often costs more than either lexical or vector search alone. It can run two candidate queries, perform fusion, and execute reranking. The cost is justified when result quality improves enough to matter.
Control cost by bounding candidate sizes, separating query classes, caching where safe, and measuring reranker use. Do not run the most expensive pipeline for every query if exact lookup is enough.
Observability Notes
Track:
- Lexical candidate latency and hit count.
- Vector candidate latency and hit count.
- Fusion overlap between paths.
- Final result source mix.
- Reranker latency and error rate.
- Zero-result rate and no-click rate.
- Filter selectivity.
- Query-set regression results.
- Relevance changes by release.
Give search engineers a way to inspect a single bad query from parse through final rank.
Backup, Restore, and DR Notes
Hybrid search recovery needs both lexical and vector validation. After restore or reindex, verify analyzers, mappings, vector fields, filters, pipelines, aliases, and reranker configuration.
If the vector path is degraded, lexical fallback may be acceptable for some workloads. Decide that before an incident. For regulated or customer-facing results, degraded mode may need feature flags and visible product behavior.
Decision Checklist
- Which query classes require hybrid retrieval?
- Which fields are lexical, vector, or both?
- Which filters are hard constraints?
- How many candidates come from BM25 and k-NN?
- How are scores normalized or fused?
- Is reranking required, and on how many candidates?
- Can a bad result be explained from logs?
- Does every path enforce tenant and entitlement filters?
- Is there a query set for release validation?
- Is rollback an alias switch, config revert, or full reindex?
What to Do Next
Problem: Hybrid search gets built as “BM25 plus vectors” without a plan for score fusion, shared filters, or reranking, and results become an opaque scoring soup nobody can debug.
Solution: Treat hybrid search as a release pipeline — normalize BM25 and k-NN scores deliberately (OpenSearch’s normalization-processor), centralize filter construction so both paths enforce the same constraints, and log pre-rerank candidates so a bad result can be traced from parse through final rank.
Proof: A protected relevance query set (including tenant-filtered negative cases) passes after every mapping, fusion, or reranker change, and a single bad query can be explained from logs without guessing.
Action: This week, confirm BM25 and vector candidates are filtered through one shared filter builder, not two independently maintained ones — that’s the most common place hybrid search leaks unauthorized results.
Sources to Verify
- OpenSearch hybrid search documentation: https://docs.opensearch.org/latest/vector-search/ai-search/hybrid-search/index/
- OpenSearch vector search and k-NN query documentation: https://docs.opensearch.org/latest/vector-search/
- OpenSearch query DSL, analyzers, and filters documentation: https://docs.opensearch.org/latest/query-dsl/
- OpenSearch normalization-processor and search pipeline documentation: https://docs.opensearch.org/latest/search-plugins/search-pipelines/normalization-processor/
- OpenSearch hybrid search explain and scoring documentation: https://docs.opensearch.org/latest/vector-search/ai-search/hybrid-search/explain/
Interactive tools for this topic