Skip to content

Commit c4e26d7

Browse files
committed
Add hybrid search
1 parent 742ef5e commit c4e26d7

File tree

4 files changed

+36
-2
lines changed

4 files changed

+36
-2
lines changed

README.md

+21
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,27 @@ JSON output:
143143
}
144144
```
145145

146+
#### Hybrid Search <!-- omit in toc -->
147+
148+
Hybrid search combines traditional keyword search with semantic search for more relevant results. You need to have an embedder configured in your index settings to use this feature.
149+
150+
```python
151+
# Using hybrid search with the search method
152+
index.search(
153+
'action movie',
154+
{
155+
"hybrid": {"semanticRatio": 0.5, "embedder": "default"}
156+
}
157+
)
158+
```
159+
160+
The `semanticRatio` parameter (between 0 and 1) controls the balance between keyword search and semantic search:
161+
- 0: Only keyword search
162+
- 1: Only semantic search
163+
- Values in between: A mix of both approaches
164+
165+
The `embedder` parameter specifies which configured embedder to use for the semantic search component.
166+
146167
#### Custom Search With Filters <!-- omit in toc -->
147168

148169
If you want to enable filtering, you must add your attributes to the `filterableAttributes` index setting.

meilisearch/index.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -280,14 +280,15 @@ def get_stats(self) -> IndexStats:
280280
def search(self, query: str, opt_params: Optional[Mapping[str, Any]] = None) -> Dict[str, Any]:
281281
"""Search in the index.
282282
283+
https://www.meilisearch.com/docs/reference/api/search
284+
283285
Parameters
284286
----------
285287
query:
286288
String containing the searched word(s)
287289
opt_params (optional):
288290
Dictionary containing optional query parameters.
289-
Note: The vector parameter is only available in Meilisearch >= v1.13.0
290-
https://www.meilisearch.com/docs/reference/api/search#search-in-an-index
291+
For hybrid search, include a 'hybrid' object with 'semanticRatio' and 'embedder' fields.
291292
292293
Returns
293294
-------
@@ -301,7 +302,9 @@ def search(self, query: str, opt_params: Optional[Mapping[str, Any]] = None) ->
301302
"""
302303
if opt_params is None:
303304
opt_params = {}
305+
304306
body = {"q": query, **opt_params}
307+
305308
return self.http.post(
306309
f"{self.config.paths.index}/{self.uid}/{self.config.paths.search}",
307310
body=body,

meilisearch/models/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

tests/index/test_index_search_meilisearch.py

+9
Original file line numberDiff line numberDiff line change
@@ -503,13 +503,22 @@ def test_show_ranking_score(index_with_documents):
503503

504504

505505
def test_vector_search(index_with_documents_and_vectors):
506+
"""Tests vector search with hybrid parameters."""
506507
response = index_with_documents_and_vectors().search(
507508
"",
508509
opt_params={"vector": [0.1, 0.2], "hybrid": {"semanticRatio": 1.0, "embedder": "default"}},
509510
)
510511
assert len(response["hits"]) > 0
511512

512513

514+
def test_hybrid_search(index_with_documents_and_vectors):
515+
"""Tests hybrid search with semantic ratio and embedder."""
516+
response = index_with_documents_and_vectors().search(
517+
"movie", opt_params={"hybrid": {"semanticRatio": 0.5, "embedder": "default"}}
518+
)
519+
assert len(response["hits"]) > 0
520+
521+
513522
def test_search_distinct(index_with_documents):
514523
index_with_documents().update_filterable_attributes(["genre"])
515524
response = index_with_documents().search("with", {"distinct": "genre"})

0 commit comments

Comments
 (0)