Files
wehub-resource-sync c56bef871b
CodeQL / Analyze (python) (push) Has been cancelled
Update Platform Components Table / update (push) Has been cancelled
Docker image release / Build base image (push) Has been cancelled
Sync docs with Docusaurus / sync (push) Has been cancelled
Tests / Check if changed (push) Has been cancelled
Tests / format (push) Has been cancelled
Tests / check-imports (push) Has been cancelled
Tests / Unit / macos-latest (push) Has been cancelled
Tests / Unit / ubuntu-latest (push) Has been cancelled
Tests / Unit / windows-latest (push) Has been cancelled
Tests / mypy (push) Has been cancelled
Tests / Integration / ubuntu-latest (push) Has been cancelled
Tests / Integration / macos-latest (push) Has been cancelled
Tests / Integration / windows-latest (push) Has been cancelled
Tests / notify-slack-on-failure (push) Has been cancelled
Tests / Mark tests as completed (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:22:28 +08:00

197 lines
7.1 KiB
Python

# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
from typing import Any
from haystack import Document, component, default_from_dict, default_to_dict
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.document_stores.types import FilterPolicy
@component
class InMemoryBM25Retriever:
"""
Retrieves documents that are most similar to the query using keyword-based algorithm.
Use this retriever with the InMemoryDocumentStore.
### Usage example
```python
from haystack import Document
from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
from haystack.document_stores.in_memory import InMemoryDocumentStore
docs = [
Document(content="Python is a popular programming language"),
Document(content="python ist eine beliebte Programmiersprache"),
]
doc_store = InMemoryDocumentStore()
doc_store.write_documents(docs)
retriever = InMemoryBM25Retriever(doc_store)
result = retriever.run(query="Programmiersprache")
print(result["documents"])
```
"""
def __init__(
self,
document_store: InMemoryDocumentStore,
filters: dict[str, Any] | None = None,
top_k: int = 10,
scale_score: bool = False,
filter_policy: FilterPolicy = FilterPolicy.REPLACE,
) -> None:
"""
Create the InMemoryBM25Retriever component.
:param document_store:
An instance of InMemoryDocumentStore where the retriever should search for relevant documents.
:param filters:
A dictionary with filters to narrow down the retriever's search space in the document store.
:param top_k:
The maximum number of documents to retrieve.
:param scale_score:
When `True`, scales the score of retrieved documents to a range of 0 to 1, where 1 means extremely relevant.
When `False`, uses raw similarity scores.
:param filter_policy: The filter policy to apply during retrieval.
Filter policy determines how filters are applied when retrieving documents. You can choose:
- `REPLACE` (default): Overrides the initialization filters with the filters specified at runtime.
Use this policy to dynamically change filtering for specific queries.
- `MERGE`: Combines runtime filters with initialization filters to narrow down the search.
:raises TypeError: If the document_store is not an instance of InMemoryDocumentStore.
:raises ValueError:
If the specified `top_k` is not > 0.
"""
if not isinstance(document_store, InMemoryDocumentStore):
raise TypeError("document_store must be an instance of InMemoryDocumentStore")
self.document_store = document_store
if top_k <= 0:
raise ValueError(f"top_k must be greater than 0. Currently, the top_k is {top_k}")
self.filters = filters
self.top_k = top_k
self.scale_score = scale_score
self.filter_policy = filter_policy
def _get_telemetry_data(self) -> dict[str, Any]:
"""
Data that is sent to Posthog for usage analytics.
"""
return {"document_store": type(self.document_store).__name__}
def to_dict(self) -> dict[str, Any]:
"""
Serializes the component to a dictionary.
:returns:
Dictionary with serialized data.
"""
return default_to_dict(
self,
document_store=self.document_store,
filters=self.filters,
top_k=self.top_k,
scale_score=self.scale_score,
filter_policy=self.filter_policy.value,
)
@classmethod
def from_dict(cls, data: dict[str, Any]) -> "InMemoryBM25Retriever":
"""
Deserializes the component from a dictionary.
:param data:
The dictionary to deserialize from.
:returns:
The deserialized component.
"""
init_params = data.get("init_parameters", {})
if "filter_policy" in init_params:
init_params["filter_policy"] = FilterPolicy.from_str(init_params["filter_policy"])
return default_from_dict(cls, data)
@component.output_types(documents=list[Document])
def run(
self,
query: str,
filters: dict[str, Any] | None = None,
top_k: int | None = None,
scale_score: bool | None = None,
) -> dict[str, list[Document]]:
"""
Run the InMemoryBM25Retriever on the given input data.
:param query:
The query string for the Retriever.
:param filters:
A dictionary with filters to narrow down the search space when retrieving documents.
:param top_k:
The maximum number of documents to return.
:param scale_score:
When `True`, scales the score of retrieved documents to a range of 0 to 1, where 1 means extremely relevant.
When `False`, uses raw similarity scores.
:returns:
The retrieved documents.
:raises ValueError:
If the specified DocumentStore is not found or is not a InMemoryDocumentStore instance.
"""
if self.filter_policy == FilterPolicy.MERGE and filters:
filters = {**(self.filters or {}), **filters}
else:
filters = filters or self.filters
if top_k is None:
top_k = self.top_k
if scale_score is None:
scale_score = self.scale_score
docs = self.document_store.bm25_retrieval(query=query, filters=filters, top_k=top_k, scale_score=scale_score)
return {"documents": docs}
@component.output_types(documents=list[Document])
async def run_async(
self,
query: str,
filters: dict[str, Any] | None = None,
top_k: int | None = None,
scale_score: bool | None = None,
) -> dict[str, list[Document]]:
"""
Run the InMemoryBM25Retriever on the given input data.
:param query:
The query string for the Retriever.
:param filters:
A dictionary with filters to narrow down the search space when retrieving documents.
:param top_k:
The maximum number of documents to return.
:param scale_score:
When `True`, scales the score of retrieved documents to a range of 0 to 1, where 1 means extremely relevant.
When `False`, uses raw similarity scores.
:returns:
The retrieved documents.
:raises ValueError:
If the specified DocumentStore is not found or is not a InMemoryDocumentStore instance.
"""
if self.filter_policy == FilterPolicy.MERGE and filters:
filters = {**(self.filters or {}), **filters}
else:
filters = filters or self.filters
if top_k is None:
top_k = self.top_k
if scale_score is None:
scale_score = self.scale_score
docs = await self.document_store.bm25_retrieval_async(
query=query, filters=filters, top_k=top_k, scale_score=scale_score
)
return {"documents": docs}