Unlock Perfect Hybrid Search in OpenSearch: My 2025 Method
Discover the definitive 2025 method for perfect hybrid search in OpenSearch. Learn to combine vector and full-text search with score normalization & RRF for superior relevance.
Dr. Alistair Finch
Principal Search Engineer specializing in OpenSearch, vector databases, and relevance engineering.
Introduction: The Search Relevance Paradox
For years, search engineers have faced a fundamental paradox. On one hand, users expect search engines to understand the intent and meaning behind their queries, a task perfectly suited for semantic vector search. On the other, they demand absolute precision for specific keywords, product codes, and jargon—the traditional domain of lexical, full-text search like BM25. For too long, we've treated these as separate worlds, often kludging them together with disappointing results.
The common approach of simply adding scores from these two disparate systems is fundamentally flawed. It's like adding meters and feet without conversion; the result is meaningless. This leads to inconsistent, unpredictable, and ultimately frustrating user experiences. In 2025, this is no longer acceptable. The solution isn't to choose one over the other, but to intelligently fuse them. This article unveils my definitive method for achieving perfect hybrid search in OpenSearch, a robust technique that leverages score normalization and Reciprocal Rank Fusion (RRF) to deliver unparalleled relevance.
What is Hybrid Search? A Quick Refresher
At its core, hybrid search is the combination of at least two different search algorithms to retrieve a single, unified set of results. In the context of modern systems like OpenSearch, this almost always refers to the marriage of:
- Lexical Search (Keyword-based): This is the classic search we've used for decades. It relies on algorithms like BM25 or TF-IDF to find documents containing the exact (or similar) keywords from a query. It excels at matching specific identifiers, names, and technical terms. Think of it as the 'what you said' search.
- Semantic Search (Vector-based): This newer approach uses machine learning models to convert both your documents and your query into numerical representations called vectors (or embeddings). It then performs a k-Nearest Neighbors (k-NN) search to find documents that are 'closest' in meaning, even if they don't share any keywords. This is the 'what you meant' search.
The power of hybrid search lies in its ability to mitigate the weaknesses of each approach. Lexical search can fail on synonyms or conceptual queries, while semantic search can sometimes miss critical, must-have keywords. By combining them, we aim for the best of both worlds: conceptual understanding with keyword precision.
The Old Way vs. The 2025 Method: Beyond Simple Combination
The naive approach to hybrid search involves running a keyword query and a vector query, then adding their raw scores together with some arbitrary weights. This fails because the scores are not on the same scale. A BM25 score is an unbounded positive number, while a cosine similarity score from a vector search is typically between -1 and 1. A high BM25 score can completely dominate a high similarity score, making the semantic part of your search useless.
My 2025 method addresses this head-on with a structured, multi-stage pipeline:
- Parallel Execution: Run both lexical and semantic queries simultaneously to get two independent result sets.
- Score Normalization: Rescale the scores from both result sets to a common range (e.g., 0 to 1).
- Intelligent Fusion: Combine the normalized results using a rank-based algorithm like Reciprocal Rank Fusion (RRF), which is more robust than simple weighted score addition.
This structured approach ensures that both search modalities contribute meaningfully to the final ranking, providing a balanced and highly relevant result set.
Step 1: Crafting the Perfect OpenSearch Index
A successful hybrid search strategy begins with a properly designed index. Your mapping must accommodate both lexical and vector data for each document. This means including a standard `text` field for full-text search and a `knn_vector` field for semantic search.
Here is a sample OpenSearch index mapping for a product catalog:
PUT /my-product-index
{
"mappings": {
"properties": {
"product_id": { "type": "keyword" },
"product_name": { "type": "text" },
"description": { "type": "text" },
"description_vector": {
"type": "knn_vector",
"dimension": 768,
"method": {
"name": "hnsw",
"space_type": "cosinesimil",
"engine": "faiss",
"parameters": {
"ef_construction": 128,
"m": 24
}
}
}
}
}
}
In this mapping, `description` is our target for BM25 keyword search, while `description_vector` will hold the 768-dimension embeddings generated from the description text by a model like `all-mpnet-base-v2`. Choosing the right embedding model is critical and depends on your specific domain and content.
Step 2: The Parallel Query Strategy
With our index in place, the next step is to query both fields simultaneously. OpenSearch makes this straightforward. We can use a `bool` query with `should` clauses, one for our keyword match and one for our k-NN vector search. This retrieves a superset of documents that match either criterion.
GET /my-product-index/_search
{
"size": 20,
"_source": ["product_name", "description"],
"query": {
"bool": {
"should": [
{
"match": {
"description": {
"query": "durable waterproof hiking boot"
}
}
},
{
"knn": {
"description_vector": {
"vector": [0.1, 0.2, ..., -0.4],
"k": 10
}
}
}
]
}
}
}
This query fetches up to 10 results from the vector search and any relevant results from the keyword search. However, the scores (`_score`) returned are still the raw, un-normalized values from each query type. This is where the real magic begins.
Step 3: The Secret Sauce - Normalization and Fusion
This is the heart of the 2025 method. We must process the results from our parallel query to create a single, coherent ranking. This involves two sub-steps: normalization and fusion.
Why Normalization is Non-Negotiable
Imagine one document gets a BM25 score of 25.7 and another gets a vector similarity score of 0.98. Which is better? It's impossible to tell. A score of 25.7 could be an average BM25 score, while 0.98 might be an exceptionally high similarity score. Without a common scale, any attempt to combine them is just guesswork. Normalization solves this by mapping both score types to a consistent range, like 0 to 1, allowing for a fair comparison.
My Preferred Normalization Technique: Min-Max Scaling
While several normalization techniques exist, Min-Max scaling is simple, effective, and intuitive for search scores. For each result set (lexical and semantic), you apply the following formula to every document score:
normalized_score = (score - min_score) / (max_score - min_score)
Here, `min_score` and `max_score` are the minimum and maximum scores within that specific result set. After this process, every document will have a lexical score between 0 and 1 and a semantic score between 0 and 1, ready for fusion. OpenSearch's `normalization-processor` can now automate this step within a search pipeline.
Fusing Scores with Reciprocal Rank Fusion (RRF)
Now that our scores are normalized, we could simply add them together. But we can do better. Reciprocal Rank Fusion (RRF) is a superior technique that de-emphasizes the absolute score values and focuses instead on the *rank* of a document in each list.
The RRF formula for a document d is:
RRF_Score(d) = Σ (1 / (k + rank_i(d)))
Where:
rank_i(d)
is the rank of document d in result set i.- The sum is over all result sets (in our case, lexical and semantic).
k
is a constant used to diminish the impact of documents with a very low rank. A common value is 60.
RRF is powerful because it values documents that appear high up in *any* of the result lists. A document that is #1 in semantic results and #10 in lexical results will likely score higher than a document that is #5 in both, something a simple weighted sum might miss.
A Tale of Three Fusion Techniques
To truly understand why the RRF-based method is superior, let's compare it to other common techniques.
Technique | How It Works | Pros | Cons |
---|---|---|---|
Simple Weighted Sum | Combines raw scores: `w1*score_lex + w2*score_sem`. | Very simple to implement. | Highly unreliable due to different score scales. Results are skewed and unpredictable. |
Normalized Weighted Sum | Combines normalized scores: `w1*norm_score_lex + w2*norm_score_sem`. | Much better than simple sum. Scores are on a comparable scale. | Still sensitive to score distribution. Can be difficult to tune the weights (w1, w2) correctly. |
Reciprocal Rank Fusion (RRF) | Combines results based on rank: `Σ(1 / (k + rank))`. | Extremely robust. Not sensitive to actual score values, only relative rank. Requires no weight tuning. | Slightly more complex to implement. May require post-processing in the application layer if not available as a native feature. |
Putting It All Together: A Complete Search Pipeline Query
OpenSearch 2.4 and later versions introduced the `search_pipeline`, which allows us to chain processors to normalize and combine results. Here’s a conceptual look at how you would define and use such a pipeline for our method.
First, define the pipeline with a normalization processor:
PUT /_search/pipeline/hybrid_search_pipeline
{
"description": "Pipeline for hybrid search with normalization and RRF-style combination",
"phase_results_processors": [
{
"normalization-processor": {
"normalization": {
"technique": "min_max"
},
"combination": {
"technique": "arithmetic_mean",
"parameters": {
"weights": [0.5, 0.5]
}
}
}
}
]
}
Note: As of early 2025, OpenSearch's native combination techniques are still evolving. While `arithmetic_mean` is shown here, implementing true RRF might still require a script processor or application-side logic. However, the normalization step is the crucial enabler and is fully supported.
Then, you simply call this pipeline in your search request:
GET /my-product-index/_search?search_pipeline=hybrid_search_pipeline
{
// ... same dual query as before ...
}
This request now automatically executes the parallel queries, normalizes the scores from each, and combines them into a single, highly relevant ranked list, giving you the power of the 2025 method directly within OpenSearch.
Conclusion: The Future of Search is Fused
The days of choosing between semantic understanding and keyword precision are over. The 2025 method for hybrid search in OpenSearch—combining parallel queries, score normalization, and Reciprocal Rank Fusion—provides a clear, robust, and reproducible path to superior search relevance. By moving beyond naive score addition and embracing a structured fusion pipeline, you can unlock a search experience that truly understands user intent while respecting the need for precision.
This isn't just a theoretical improvement; it's a practical, implementable strategy that will set your application's search capabilities apart. Stop compromising and start fusing. Your users will thank you for it.