chore: import upstream snapshot with attribution
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

This commit is contained in:
wehub-resource-sync
2026-07-13 13:22:28 +08:00
commit c56bef871b
9296 changed files with 1854228 additions and 0 deletions
@@ -0,0 +1,100 @@
---
title: "ArcadeDBEmbeddingRetriever"
id: arcadedbembeddingretriever
slug: "/arcadedbembeddingretriever"
description: "An embedding-based Retriever compatible with the ArcadeDB Document Store."
---
# ArcadeDBEmbeddingRetriever
An embedding-based Retriever compatible with the ArcadeDB Document Store. It uses ArcadeDB's LSM_VECTOR (HNSW) index for vector similarity search.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [ChatPromptBuilder](../builders/chatpromptbuilder.mdx) in a RAG pipeline 2. The last component in a semantic search pipeline |
| **Mandatory init variables** | `document_store`: An instance of [ArcadeDBDocumentStore](../../document-stores/arcadedbdocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A vector representing the query (a list of floats) |
| **Output variables** | `documents`: A list of documents |
| **API reference** | [ArcadeDB](/reference/integrations-arcadedb) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/arcadedb |
</div>
## Overview
The `ArcadeDBEmbeddingRetriever` retrieves documents from `ArcadeDBDocumentStore` by comparing the query embedding with document embeddings using the store's HNSW index. It accepts optional `filters` for metadata filtering and `top_k` to limit the number of results. Use a Document Embedder in your indexing pipeline and a Text Embedder in your query pipeline so embeddings are available.
## Installation
```shell
pip install arcadedb-haystack
```
Ensure ArcadeDB is running, for example via Docker, and credentials are set (`ARCADEDB_USERNAME`, `ARCADEDB_PASSWORD`).
## Usage
### On its own
```python
from haystack_integrations.document_stores.arcadedb import ArcadeDBDocumentStore
from haystack_integrations.components.retrievers.arcadedb import ArcadeDBEmbeddingRetriever
document_store = ArcadeDBDocumentStore(
url="http://localhost:2480",
database="haystack",
embedding_dimension=768,
)
retriever = ArcadeDBEmbeddingRetriever(document_store=document_store, top_k=5)
# Example: run with a query embedding (e.g. from an embedder)
result = retriever.run(query_embedding=[0.1] * 768)
for doc in result["documents"]:
print(doc.content)
```
### In a pipeline
```python
from haystack import Document, Pipeline
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.embedders import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
from haystack_integrations.document_stores.arcadedb import ArcadeDBDocumentStore
from haystack_integrations.components.retrievers.arcadedb import ArcadeDBEmbeddingRetriever
document_store = ArcadeDBDocumentStore(
url="http://localhost:2480",
database="haystack",
embedding_dimension=768,
recreate_type=True,
)
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(content="Elephants have been observed to recognize themselves in mirrors."),
Document(content="Bioluminescent waves can be seen in the Maldives and Puerto Rico."),
]
document_embedder = SentenceTransformersDocumentEmbedder()
documents_with_embeddings = document_embedder.run(documents)
document_store.write_documents(
documents_with_embeddings["documents"],
policy=DuplicatePolicy.OVERWRITE,
)
query_pipeline = Pipeline()
query_pipeline.add_component("text_embedder", SentenceTransformersTextEmbedder())
query_pipeline.add_component(
"retriever",
ArcadeDBEmbeddingRetriever(document_store=document_store, top_k=3),
)
query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
result = query_pipeline.run({"text_embedder": {"text": "How many languages are there?"}})
print(result["retriever"]["documents"][0])
```
@@ -0,0 +1,116 @@
---
title: "AstraEmbeddingRetriever"
id: astraretriever
slug: "/astraretriever"
description: "This is an embedding-based Retriever compatible with the Astra Document Store."
---
# AstraEmbeddingRetriever
This is an embedding-based Retriever compatible with the Astra Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline <br /> 2. The last component in the semantic search pipeline <br /> 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of [AstraDocumentStore](../../document-stores/astradocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents |
| **API reference** | [Astra](/reference/integrations-astra) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/astra |
</div>
## Overview
`AstraEmbeddingRetriever` compares the query and document embeddings and fetches the documents most relevant to the query from the [`AstraDocumentStore`](../../document-stores/astradocumentstore.mdx) based on the outcome.
When using the `AstraEmbeddingRetriever` in your NLP system, make sure it has the query and document embeddings available. You can do so by adding a Document Embedder to your indexing pipeline and a Text Embedder to your query pipeline.
In addition to the `query_embedding`, the `AstraEmbeddingRetriever` accepts other optional parameters, including `top_k` (the maximum number of documents to retrieve) and `filters` to narrow down the search space.
### Setup and installation
Once you have an AstraDB account and have created a database, install the `astra-haystack` integration:
```shell
pip install astra-haystack
```
From the configuration in AstraDBs web UI, you need the database ID and a generated token.
You will additionally need a collection name and a namespace. When you create the collection name, you also need to set the embedding dimensions and the similarity metric. The namespace organizes data in a database and is called a keyspace in Apache Cassandra.
Then, optionally, install sentence-transformers as well to run the example below:
```shell
pip install sentence-transformers
```
## Usage
We strongly encourage passing authentication data through environment variables: make sure to populate the environment variables `ASTRA_DB_API_ENDPOINT` and `ASTRA_DB_APPLICATION_TOKEN` before running the following example.
### In a pipeline
Use this Retriever in a query pipeline like this:
```python
from haystack import Document, Pipeline
from haystack.components.embedders import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
from haystack_integrations.components.retrievers.astra import AstraEmbeddingRetriever
from haystack_integrations.document_stores.astra import AstraDocumentStore
document_store = AstraDocumentStore()
model = "sentence-transformers/all-mpnet-base-v2"
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
document_embedder = SentenceTransformersDocumentEmbedder(model=model)
documents_with_embeddings = document_embedder.run(documents)
document_store.write_documents(
documents_with_embeddings.get("documents"),
policy=DuplicatePolicy.SKIP,
)
query_pipeline = Pipeline()
query_pipeline.add_component(
"text_embedder",
SentenceTransformersTextEmbedder(model=model),
)
query_pipeline.add_component(
"retriever",
AstraEmbeddingRetriever(document_store=document_store),
)
query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
query = "How many languages are there?"
result = query_pipeline.run({"text_embedder": {"text": query}})
print(result["retriever"]["documents"][0])
```
The example output would be:
```python
Document(id=cfe93bc1c274908801e6670440bf2bbba54fad792770d57421f85ffa2a4fcc94, content: 'There are over 7,000 languages spoken around the world today.', score: 0.8929937, embedding: vector of size 768)
```
## Additional References
🧑‍🍳 Cookbook: [Using AstraDB as a data store in your Haystack pipelines](https://haystack.deepset.ai/cookbook/astradb_haystack_integration)
@@ -0,0 +1,172 @@
---
title: "AutoMergingRetriever"
id: automergingretriever
slug: "/automergingretriever"
description: "Use AutoMergingRetriever to improve search results by returning complete parent documents instead of fragmented chunks when multiple related pieces match a query."
---
# AutoMergingRetriever
Use AutoMergingRetriever to improve search results by returning complete parent documents instead of fragmented chunks when multiple related pieces match a query.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | Used after the main Retriever component that returns hierarchical documents. |
| **Mandatory init variables** | `document_store`: Document Store from which to retrieve the parent documents |
| **Mandatory run variables** | `documents`: A list of leaf documents that were matched by a Retriever |
| **Output variables** | `documents`: A list resulting documents |
| **API reference** | [Retrievers](/reference/retrievers-api) |
| **GitHub link** | [https://github.com/deepset-ai/haystack/blob/dae8c7babaf28d2ffab4f2a8dedecd63e2394fb4/haystack/components/retrievers/auto_merging_retriever.py](https://github.com/deepset-ai/haystack/blob/dae8c7babaf28d2ffab4f2a8dedecd63e2394fb4/haystack/components/retrievers/auto_merging_retriever.py#L116) |
</div>
## Overview
The `AutoMergingRetriever` is a component that works with a hierarchical document structure. It returns the parent documents instead of individual leaf documents when a certain threshold is met.
This can be particularly useful when working with paragraphs split into multiple chunks. When several chunks from the same paragraph match your query, the complete paragraph often provides more context and value than the individual pieces alone.
Here is how this Retriever works:
1. It requires documents to be organized in a tree structure, with leaf nodes stored in a document index - see [`HierarchicalDocumentSplitter`](../preprocessors/hierarchicaldocumentsplitter.mdx) documentation.
2. When searching, it counts how many leaf documents under the same parent match your query.
3. If this count exceeds your defined threshold, it returns the parent document instead of the individual leaves.
The `AutoMergingRetriever` can currently be used by the following Document Stores:
- [AstraDocumentStore](../../document-stores/astradocumentstore.mdx)
- [ElasticsearchDocumentStore](../../document-stores/elasticsearch-document-store.mdx)
- [OpenSearchDocumentStore](../../document-stores/opensearch-document-store.mdx)
- [PgvectorDocumentStore](../../document-stores/pgvectordocumentstore.mdx)
- [QdrantDocumentStore](../../document-stores/qdrant-document-store.mdx)
## Usage
### On its own
```python
from haystack import Document
from haystack.components.preprocessors import HierarchicalDocumentSplitter
from haystack.components.retrievers.auto_merging_retriever import AutoMergingRetriever
from haystack.document_stores.in_memory import InMemoryDocumentStore
## create a hierarchical document structure with 3 levels, where the parent document has 3 children
text = "The sun rose early in the morning. It cast a warm glow over the trees. Birds began to sing."
original_document = Document(content=text)
builder = HierarchicalDocumentSplitter(block_sizes=[10, 3], split_overlap=0, split_by="word")
docs = builder.run([original_document])["documents"]
## store level-1 parent documents and initialize the retriever
doc_store_parents = InMemoryDocumentStore()
for doc in docs["documents"]:
if doc.meta["children_ids"] and doc.meta["level"] == 1:
doc_store_parents.write_documents([doc])
retriever = AutoMergingRetriever(doc_store_parents, threshold=0.5)
## assume we retrieved 2 leaf docs from the same parent, the parent document should be returned,
## since it has 3 children and the threshold=0.5, and we retrieved 2 children (2/3 > 0.66(6))
leaf_docs = [doc for doc in docs["documents"] if not doc.meta["children_ids"]]
docs = retriever.run(leaf_docs[4:6])
>> {'documents': [Document(id=538..),
>> content: 'warm glow over the trees. Birds began to sing.',
>> meta: {'block_size': 10, 'parent_id': '835..', 'children_ids': ['c17...', '3ff...', '352...'], 'level': 1, 'source_id': '835...',
>> 'page_number': 1, 'split_id': 1, 'split_idx_start': 45})]}
```
### In a pipeline
This is an example of a RAG Haystack pipeline. It first retrieves leaf-level document chunks using BM25, merges them into higher-level parent documents with `AutoMergingRetriever`, constructs a prompt, and generates an answer using OpenAI's chat model.
```python
from typing import List, Tuple
from haystack import Document, Pipeline
from haystack_experimental.components.splitters import HierarchicalDocumentSplitter
from haystack.components.builders.answer_builder import AnswerBuilder
from haystack.components.builders.chat_prompt_builder import ChatPromptBuilder
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
from haystack.components.retrievers import AutoMergingRetriever
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.document_stores.types import DuplicatePolicy
from haystack.dataclasses import ChatMessage
def indexing(
documents: List[Document],
) -> Tuple[InMemoryDocumentStore, InMemoryDocumentStore]:
splitter = HierarchicalDocumentSplitter(
block_sizes={10, 3},
split_overlap=0,
split_by="word",
)
docs = splitter.run(documents)
leaf_documents = [doc for doc in docs["documents"] if doc.meta["__level"] == 1]
leaf_doc_store = InMemoryDocumentStore()
leaf_doc_store.write_documents(leaf_documents, policy=DuplicatePolicy.OVERWRITE)
parent_documents = [doc for doc in docs["documents"] if doc.meta["__level"] == 0]
parent_doc_store = InMemoryDocumentStore()
parent_doc_store.write_documents(parent_documents, policy=DuplicatePolicy.OVERWRITE)
return leaf_doc_store, parent_doc_store
## Add documents
docs = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
leaf_docs, parent_docs = indexing(docs)
prompt_template = [
ChatMessage.from_system("You are a helpful assistant."),
ChatMessage.from_user(
"Given these documents, answer the question.\nDocuments:\n"
"{% for doc in documents %}{{ doc.content }}{% endfor %}\n"
"Question: {{question}}\nAnswer:",
),
]
rag_pipeline = Pipeline()
rag_pipeline.add_component(
instance=InMemoryBM25Retriever(document_store=leaf_docs),
name="bm25_retriever",
)
rag_pipeline.add_component(
instance=AutoMergingRetriever(parent_docs, threshold=0.6),
name="retriever",
)
rag_pipeline.add_component(
instance=ChatPromptBuilder(
template=prompt_template,
required_variables={"question", "documents"},
),
name="prompt_builder",
)
rag_pipeline.add_component(instance=OpenAIChatGenerator(), name="llm")
rag_pipeline.add_component(instance=AnswerBuilder(), name="answer_builder")
rag_pipeline.connect("bm25_retriever.documents", "retriever.documents")
rag_pipeline.connect("retriever", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder.messages", "llm.messages")
rag_pipeline.connect("llm.replies", "answer_builder.replies")
rag_pipeline.connect("retriever", "answer_builder.documents")
question = "How many languages are there?"
result = rag_pipeline.run(
{
"bm25_retriever": {"query": question},
"prompt_builder": {"question": question},
"answer_builder": {"query": question},
},
)
```
@@ -0,0 +1,153 @@
---
title: "AzureAISearchBM25Retriever"
id: azureaisearchbm25retriever
slug: "/azureaisearchbm25retriever"
description: "A keyword-based Retriever that fetches Documents matching a query from the Azure AI Search Document Store."
---
# AzureAISearchBM25Retriever
A keyword-based Retriever that fetches Documents matching a query from the Azure AI Search Document Store.
A keyword-based Retriever that fetches documents matching a query from the Azure AI Search Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. Before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. Before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of [`AzureAISearchDocumentStore`](../../document-stores/azureaisearchdocumentstore.mdx) |
| **Mandatory run variables** | `query`: A string |
| **Output variables** | `documents`: A list of documents (matching the query) |
| **API reference** | [Azure AI Search](/reference/integrations-azure_ai_search) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/azure_ai_search |
</div>
## Overview
The `AzureAISearchBM25Retriever` is a keyword-based Retriever designed to fetch documents that match a query from an `AzureAISearchDocumentStore`. It uses the BM25 algorithm which calculates a weighted word overlap between the query and the documents to determine their similarity. The Retriever accepts textual query but you can also provide a combination of terms with boolean operators. Some examples of valid queries could be `"pool"`, `"pool spa"`, and `"pool spa +airport"`.
In addition to the `query`, the `AzureAISearchBM25Retriever` accepts other optional parameters, including `top_k` (the maximum number of documents to retrieve) and `filters` to narrow down the search space.
If your search index includes a [semantic configuration](https://learn.microsoft.com/en-us/azure/search/semantic-how-to-query-request), you can enable semantic ranking to apply it to the Retriever's results. For more details, refer to the [Azure AI documentation](https://learn.microsoft.com/en-us/azure/search/hybrid-search-how-to-query#semantic-hybrid-search).
If you want a combination of BM25 and vector retrieval, use the `AzureAISearchHybridRetriever`, which uses both vector search and BM25 search to match documents and query.
## Usage
### Installation
This integration requires you to have an active Azure subscription with a deployed [Azure AI Search](https://azure.microsoft.com/en-us/products/ai-services/ai-search) service.
To start using Azure AI search with Haystack, install the package with:
```shell
pip install azure-ai-search-haystack
```
### On its own
This Retriever needs `AzureAISearchDocumentStore` and indexed documents to run.
```python
from haystack import Document
from haystack_integrations.components.retrievers.azure_ai_search import (
AzureAISearchBM25Retriever,
)
from haystack_integrations.document_stores.azure_ai_search import (
AzureAISearchDocumentStore,
)
document_store = AzureAISearchDocumentStore(index_name="haystack_docs")
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
document_store.write_documents(documents=documents)
retriever = AzureAISearchBM25Retriever(document_store=document_store)
retriever.run(query="How many languages are spoken around the world today?")
```
### In a RAG pipeline
The below example shows how to use the `AzureAISearchBM25Retriever` in a RAG pipeline. Set your `OPENAI_API_KEY` as an environment variable and then run the following code:
```python
from haystack_integrations.components.retrievers.azure_ai_search import (
AzureAISearchBM25Retriever,
)
from haystack_integrations.document_stores.azure_ai_search import (
AzureAISearchDocumentStore,
)
from haystack import Document
from haystack import Pipeline
from haystack.components.builders.answer_builder import AnswerBuilder
from haystack.components.builders.prompt_builder import PromptBuilder
from haystack.components.generators import OpenAIGenerator
from haystack.document_stores.types import DuplicatePolicy
import os
api_key = os.environ["OPENAI_API_KEY"]
## Create a RAG query pipeline
prompt_template = """
Given these documents, answer the question.\nDocuments:
{% for doc in documents %}
{{ doc.content }}
{% endfor %}
\nQuestion: {{question}}
\nAnswer:
"""
document_store = AzureAISearchDocumentStore(index_name="haystack-docs")
## Add Documents
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
## policy param is optional, as AzureAISearchDocumentStore has a default policy of DuplicatePolicy.OVERWRITE
document_store.write_documents(documents=documents, policy=DuplicatePolicy.OVERWRITE)
retriever = AzureAISearchBM25Retriever(document_store=document_store)
rag_pipeline = Pipeline()
rag_pipeline.add_component(name="retriever", instance=retriever)
rag_pipeline.add_component(
instance=PromptBuilder(template=prompt_template),
name="prompt_builder",
)
rag_pipeline.add_component(instance=OpenAIGenerator(), name="llm")
rag_pipeline.add_component(instance=AnswerBuilder(), name="answer_builder")
rag_pipeline.connect("retriever", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder", "llm")
rag_pipeline.connect("llm.replies", "answer_builder.replies")
rag_pipeline.connect("llm.meta", "answer_builder.meta")
rag_pipeline.connect("retriever", "answer_builder.documents")
question = "Tell me something about languages?"
result = rag_pipeline.run(
{
"retriever": {"query": question},
"prompt_builder": {"question": question},
"answer_builder": {"query": question},
},
)
print(result["answer_builder"]["answers"][0])
```
@@ -0,0 +1,143 @@
---
title: "AzureAISearchEmbeddingRetriever"
id: azureaisearchembeddingretriever
slug: "/azureaisearchembeddingretriever"
description: "An embedding Retriever compatible with the Azure AI Search Document Store."
---
# AzureAISearchEmbeddingRetriever
An embedding Retriever compatible with the Azure AI Search Document Store.
This Retriever accepts the embeddings of a single query as input and returns a list of matching documents.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the embedding retrieval pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of [`AzureAISearchDocumentStore`](../../document-stores/azureaisearchdocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents |
| **API reference** | [Azure AI Search](/reference/integrations-azure_ai_search) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/azure_ai_search |
</div>
## Overview
The `AzureAISearchEmbeddingRetriever` is an embedding-based Retriever compatible with the `AzureAISearchDocumentStore`. It compares the query and document embeddings and fetches the most relevant documents from the `AzureAISearchDocumentStore` based on the outcome.
The query needs to be embedded before being passed to this component. For example, you could use a Text [Embedder](../embedders.mdx) component.
By default, the `AzureAISearchDocumentStore` uses the [HNSW algorithm](https://learn.microsoft.com/en-us/azure/search/vector-search-overview#nearest-neighbors-search) with cosine similarity to handle vector searches. The vector configuration is set during the initialization of the document store and can be customized by providing the `vector_search_configuration` parameter.
In addition to the `query_embedding`, the `AzureAISearchEmbeddingRetriever` accepts other optional parameters, including `top_k` (the maximum number of documents to retrieve) and `filters` to narrow down the search space.
:::info[Semantic Ranking]
The semantic ranking capability of Azure AI Search is not available for vector retrieval. To include semantic ranking in your retrieval process, use the [`AzureAISearchBM25Retriever`](azureaisearchbm25retriever.mdx) or [`AzureAISearchHybridRetriever`](azureaisearchhybridretriever.mdx). For more details, see [Azure AI documentation](https://learn.microsoft.com/en-us/azure/search/semantic-how-to-query-request?tabs=portal-query#set-up-the-query).
:::
## Usage
### Installation
This integration requires you to have an active Azure subscription with a deployed [Azure AI Search](https://azure.microsoft.com/en-us/products/ai-services/ai-search) service.
To start using Azure AI search with Haystack, install the package with:
```shell
pip install azure-ai-search-haystack
```
### On its own
This Retriever needs `AzureAISearchDocumentStore` and indexed documents to run.
```python
from haystack_integrations.document_stores.azure_ai_search import (
AzureAISearchDocumentStore,
)
from haystack_integrations.components.retrievers.azure_ai_search import (
AzureAISearchEmbeddingRetriever,
)
document_store = AzureAISearchDocumentStore()
retriever = AzureAISearchEmbeddingRetriever(document_store=document_store)
## example run query
retriever.run(query_embedding=[0.1] * 384)
```
### In a pipeline
Here is how you could use the `AzureAISearchEmbeddingRetriever` in a pipeline. In this example, you would create two pipelines: an indexing one and a querying one.
In the indexing pipeline, the documents are passed to the Document Embedder and then written into the Document Store.
Then, in the querying pipeline, we use a Text Embedder to get the vector representation of the input query that will be then passed to the `AzureAISearchEmbeddingRetriever` to get the results.
```python
from haystack import Document, Pipeline
from haystack.components.embedders import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
from haystack.components.writers import DocumentWriter
from haystack_integrations.components.retrievers.azure_ai_search import (
AzureAISearchEmbeddingRetriever,
)
from haystack_integrations.document_stores.azure_ai_search import (
AzureAISearchDocumentStore,
)
document_store = AzureAISearchDocumentStore(index_name="retrieval-example")
model = "sentence-transformers/all-mpnet-base-v2"
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="""Elephants have been observed to behave in a way that indicates a
high level of self-awareness, such as recognizing themselves in mirrors.""",
),
Document(
content="""In certain parts of the world, like the Maldives, Puerto Rico, and
San Diego, you can witness the phenomenon of bioluminescent waves.""",
),
]
document_embedder = SentenceTransformersDocumentEmbedder(model=model)
## Indexing Pipeline
indexing_pipeline = Pipeline()
indexing_pipeline.add_component(instance=document_embedder, name="doc_embedder")
indexing_pipeline.add_component(
instance=DocumentWriter(document_store=document_store),
name="doc_writer",
)
indexing_pipeline.connect("doc_embedder", "doc_writer")
indexing_pipeline.run({"doc_embedder": {"documents": documents}})
## Query Pipeline
query_pipeline = Pipeline()
query_pipeline.add_component(
"text_embedder",
SentenceTransformersTextEmbedder(model=model),
)
query_pipeline.add_component(
"retriever",
AzureAISearchEmbeddingRetriever(document_store=document_store),
)
query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
query = "How many languages are there?"
result = query_pipeline.run({"text_embedder": {"text": query}})
print(result["retriever"]["documents"][0])
```
@@ -0,0 +1,149 @@
---
title: "AzureAISearchHybridRetriever"
id: azureaisearchhybridretriever
slug: "/azureaisearchhybridretriever"
description: "A Retriever based both on dense and sparse embeddings, compatible with the Azure AI Search Document Store."
---
# AzureAISearchHybridRetriever
A Retriever based both on dense and sparse embeddings, compatible with the Azure AI Search Document Store.
This Retriever combines embedding-based retrieval and BM25 text search search to find matching documents in the search index to get more relevant results.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a TextEmbedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in a hybrid search pipeline 3. After a TextEmbedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of [`AzureAISearchDocumentStore`](../../document-stores/azureaisearchdocumentstore.mdx) |
| **Mandatory run variables** | `query`: A string <br /> <br />`query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents (matching the query) |
| **API reference** | [Azure AI Search](/reference/integrations-azure_ai_search) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/azure_ai_search |
</div>
## Overview
The `AzureAISearchHybridRetriever` combines vector retrieval and BM25 text search to fetch relevant documents from the `AzureAISearchDocumentStore`. It processes both textual (keyword) queries and query embeddings in a single request, executing all subqueries in parallel. The results are merged and reordered using [Reciprocal Rank Fusion (RRF)](https://learn.microsoft.com/en-us/azure/search/hybrid-search-ranking) to create a unified result set.
Besides the `query` and `query_embedding`, the `AzureAISearchHybridRetriever` accepts optional parameters such as `top_k` (the maximum number of documents to retrieve) and `filters` to refine the search. Additional keyword arguments can also be passed during initialization for further customization.
If your search index includes a [semantic configuration](https://learn.microsoft.com/en-us/azure/search/semantic-how-to-query-request), you can enable semantic ranking to apply it to the Retriever's results. For more details, refer to the [Azure AI documentation](https://learn.microsoft.com/en-us/azure/search/hybrid-search-how-to-query#semantic-hybrid-search).
For purely keyword-based retrieval, you can use `AzureAISearchBM25Retriever`, and for embedding-based retrieval, `AzureAISearchEmbeddingRetriever` is available.
## Usage
### Installation
This integration requires you to have an active Azure subscription with a deployed [Azure AI Search](https://azure.microsoft.com/en-us/products/ai-services/ai-search) service.
To start using Azure AI search with Haystack, install the package with:
```shell
pip install azure-ai-search-haystack
```
### On its own
This Retriever needs `AzureAISearchDocumentStore` and indexed documents to run.
```python
from haystack import Document
from haystack_integrations.components.retrievers.azure_ai_search import (
AzureAISearchHybridRetriever,
)
from haystack_integrations.document_stores.azure_ai_search import (
AzureAISearchDocumentStore,
)
document_store = AzureAISearchDocumentStore(index_name="haystack_docs")
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
document_store.write_documents(documents=documents)
retriever = AzureAISearchHybridRetriever(document_store=document_store)
## fake embeddings to keep the example simple
retriever.run(
query="How many languages are spoken around the world today?",
query_embedding=[0.1] * 384,
)
```
### In a RAG pipeline
The following example demonstrates using the `AzureAISearchHybridRetriever` in a pipeline. An indexing pipeline is responsible for indexing and storing documents with embeddings in the `AzureAISearchDocumentStore`, while the query pipeline uses hybrid retrieval to fetch relevant documents based on a given query.
```python
from haystack import Document, Pipeline
from haystack.components.embedders import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
from haystack.components.writers import DocumentWriter
from haystack_integrations.components.retrievers.azure_ai_search import (
AzureAISearchHybridRetriever,
)
from haystack_integrations.document_stores.azure_ai_search import (
AzureAISearchDocumentStore,
)
document_store = AzureAISearchDocumentStore(index_name="hybrid-retrieval-example")
model = "sentence-transformers/all-mpnet-base-v2"
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="""Elephants have been observed to behave in a way that indicates a
high level of self-awareness, such as recognizing themselves in mirrors.""",
),
Document(
content="""In certain parts of the world, like the Maldives, Puerto Rico, and
San Diego, you can witness the phenomenon of bioluminescent waves.""",
),
]
document_embedder = SentenceTransformersDocumentEmbedder(model=model)
## Indexing Pipeline
indexing_pipeline = Pipeline()
indexing_pipeline.add_component(instance=document_embedder, name="doc_embedder")
indexing_pipeline.add_component(
instance=DocumentWriter(document_store=document_store),
name="doc_writer",
)
indexing_pipeline.connect("doc_embedder", "doc_writer")
indexing_pipeline.run({"doc_embedder": {"documents": documents}})
## Query Pipeline
query_pipeline = Pipeline()
query_pipeline.add_component(
"text_embedder",
SentenceTransformersTextEmbedder(model=model),
)
query_pipeline.add_component(
"retriever",
AzureAISearchHybridRetriever(document_store=document_store),
)
query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
query = "How many languages are there?"
result = query_pipeline.run(
{"text_embedder": {"text": query}, "retriever": {"query": query}},
)
print(result["retriever"]["documents"][0])
```
@@ -0,0 +1,111 @@
---
title: "ChromaEmbeddingRetriever"
id: chromaembeddingretriever
slug: "/chromaembeddingretriever"
description: "This is an embedding Retriever compatible with the Chroma Document Store."
---
# ChromaEmbeddingRetriever
This is an embedding Retriever compatible with the Chroma Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [ChromaDocumentStore](../../document-stores/chromadocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents |
| **API reference** | [Chroma](/reference/integrations-chroma) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/chroma |
</div>
## Overview
The `ChromaEmbeddingRetriever` is an embedding-based Retriever compatible with the `ChromaDocumentStore`. It compares the query and document embeddings and fetches the documents most relevant to the query from the `ChromaDocumentStore` based on the outcome.
The query needs to be embedded before being passed to this component. For example, you could use a text [embedder](../embedders.mdx) component.
In addition to the `query_embedding`, the `ChromaEmbeddingRetriever` accepts other optional parameters, including `top_k` (the maximum number of documents to retrieve) and `filters` to narrow down the search space.
### Usage
#### On its own
This Retriever needs the `ChromaDocumentStore` and indexed documents to run.
```python
from haystack_integrations.document_stores.chroma import ChromaDocumentStore
from haystack_integrations.components.retrievers.chroma import ChromaEmbeddingRetriever
document_store = ChromaDocumentStore()
retriever = ChromaEmbeddingRetriever(document_store=document_store)
## example run query
retriever.run(query_embedding=[0.1] * 384)
```
#### In a pipeline
Here is how you could use the `ChromaEmbeddingRetriever` in a pipeline. In this example, you would create two pipelines: an indexing one and a querying one.
In the indexing pipeline, the documents are passed to the Document Embedder and then written into the document Store.
Then, in the querying pipeline, we use a text embedder to get the vector representation of the input query that will be then passed to the `ChromaEmbeddingRetriever` to get the results.
```python
import os
from pathlib import Path
from haystack import Pipeline
from haystack.dataclasses import Document
from haystack.components.writers import DocumentWriter
## Note: the following requires a "pip install sentence-transformers"
from haystack.components.embedders import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
from haystack_integrations.document_stores.chroma import ChromaDocumentStore
from haystack_integrations.components.retrievers.chroma import ChromaEmbeddingRetriever
from sentence_transformers import SentenceTransformer
## Chroma is used in-memory so we use the same instances in the two pipelines below
document_store = ChromaDocumentStore()
documents = [
Document(content="This contains variable declarations", meta={"title": "one"}),
Document(
content="This contains another sort of variable declarations",
meta={"title": "two"},
),
Document(
content="This has nothing to do with variable declarations",
meta={"title": "three"},
),
Document(content="A random doc", meta={"title": "four"}),
]
indexing = Pipeline()
indexing.add_component("embedder", SentenceTransformersDocumentEmbedder())
indexing.add_component("writer", DocumentWriter(document_store))
indexing.connect("embedder.documents", "writer.documents")
indexing.run({"embedder": {"documents": documents}})
querying = Pipeline()
querying.add_component("query_embedder", SentenceTransformersTextEmbedder())
querying.add_component("retriever", ChromaEmbeddingRetriever(document_store))
querying.connect("query_embedder.embedding", "retriever.query_embedding")
results = querying.run({"query_embedder": {"text": "Variable declarations"}})
for d in results["retriever"]["documents"]:
print(d.meta, d.score)
```
## Additional References
🧑‍🍳 Cookbook: [Use Chroma for RAG and Indexing](https://haystack.deepset.ai/cookbook/chroma-indexing-and-rag-examples)
@@ -0,0 +1,98 @@
---
title: "ChromaQueryTextRetriever"
id: chromaqueryretriever
slug: "/chromaqueryretriever"
description: "This is a a Retriever compatible with the Chroma Document Store."
---
# ChromaQueryTextRetriever
This is a a Retriever compatible with the Chroma Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [ChromaDocumentStore](../../document-stores/chromadocumentstore.mdx) |
| **Mandatory run variables** | `query`: A single query in plain-text format to be processed by the [Retriever](../retrievers.mdx) |
| **Output variables** | `documents`: A list of documents |
| **API reference** | [Chroma](/reference/integrations-chroma) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/chroma |
</div>
## Overview
The `ChromaQueryTextRetriever` is an embedding-based Retriever compatible with the `ChromaDocumentStore` that uses the Chroma [query API](https://docs.trychroma.com/reference/Collection#query).
This component takes a plain-text query string in input and returns the matching documents.
Chroma will create the embedding for the query using its [embedding function](https://docs.trychroma.com/embeddings#default-all-minilm-l6-v2); in case you do not want to use the default embedding function, this must be specified at `ChromaDocumentStore` initialization.
### Usage
#### On its own
This Retriever needs the `ChromaDocumentStore` and indexed documents to run.
```python
from haystack_integrations.document_stores.chroma import ChromaDocumentStore
from haystack_integrations.components.retrievers.chroma import ChromaQueryTextRetriever
document_store = ChromaDocumentStore()
retriever = ChromaQueryTextRetriever(document_store=document_store)
## example run query
retriever.run(query="How does Chroma Retriever work?")
```
#### In a pipeline
Here is how you could use the `ChromaQueryTextRetriever` in a Pipeline. In this example, you would create two pipelines: an indexing one and a querying one.
In the indexing pipeline, the documents are written in the Document Store.
Then, in the querying pipeline, `ChromaQueryTextRetriever` gets the answer from the Document Store based on the provided query.
```python
import os
from pathlib import Path
from haystack import Pipeline
from haystack.dataclasses import Document
from haystack.components.writers import DocumentWriter
from haystack_integrations.document_stores.chroma import ChromaDocumentStore
from haystack_integrations.components.retrievers.chroma import ChromaQueryTextRetriever
## Chroma is used in-memory so we use the same instances in the two pipelines below
document_store = ChromaDocumentStore()
documents = [
Document(content="This contains variable declarations", meta={"title": "one"}),
Document(
content="This contains another sort of variable declarations",
meta={"title": "two"},
),
Document(
content="This has nothing to do with variable declarations",
meta={"title": "three"},
),
Document(content="A random doc", meta={"title": "four"}),
]
indexing = Pipeline()
indexing.add_component("writer", DocumentWriter(document_store))
indexing.run({"writer": {"documents": documents}})
querying = Pipeline()
querying.add_component("retriever", ChromaQueryTextRetriever(document_store))
results = querying.run({"retriever": {"query": "Variable declarations", "top_k": 3}})
for d in results["retriever"]["documents"]:
print(d.meta, d.score)
```
## Additional References
🧑‍🍳 Cookbook: [Use Chroma for RAG and Indexing](https://haystack.deepset.ai/cookbook/chroma-indexing-and-rag-examples)
@@ -0,0 +1,173 @@
---
title: "ElasticsearchBM25Retriever"
id: elasticsearchbm25retriever
slug: "/elasticsearchbm25retriever"
description: "A keyword-based Retriever that fetches Documents matching a query from the Elasticsearch Document Store."
---
# ElasticsearchBM25Retriever
A keyword-based Retriever that fetches Documents matching a query from the Elasticsearch Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. Before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. Before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of [ElasticsearchDocumentStore](../../document-stores/elasticsearch-document-store.mdx) |
| **Mandatory run variables** | `query`: A string |
| **Output variables** | `documents`: A list of documents (matching the query) |
| **API reference** | [Elasticsearch](/reference/integrations-elasticsearch) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/elasticsearch |
</div>
## Overview
`ElasticsearchBM25Retriever` is a keyword-based Retriever that fetches Documents matching a query from an `ElasticsearchDocumentStore`. It determines the similarity between Documents and the query based on the BM25 algorithm, which computes a weighted word overlap between the two strings.
Since the `ElasticsearchBM25Retriever` matches strings based on word overlap, its often used to find exact matches to names of persons or products, IDs, or well-defined error messages. The BM25 algorithm is very lightweight and simple. Nevertheless, it can be hard to beat with more complex embedding-based approaches on out-of-domain data.
In addition to the `query`, the `ElasticsearchBM25Retriever` accepts other optional parameters, including `top_k` (the maximum number of Documents to retrieve) and `filters` to narrow down the search space.
When initializing Retriever, you can also adjust how [inexact fuzzy matching](https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#fuzziness) is performed, using the `fuzziness` parameter.
If you want a semantic match between a query and documents, you can use `ElasticsearchEmbeddingRetriever`, which uses vectors created by embedding models to retrieve relevant information.
## Installation
[Install](https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html) Elasticsearch and then [start](https://www.elastic.co/guide/en/elasticsearch/reference/current/starting-elasticsearch.html) an instance. Haystack supports Elasticsearch 8.
If you have Docker set up, we recommend pulling the Docker image and running it.
```shell
docker pull docker.elastic.co/elasticsearch/elasticsearch:8.11.1
docker run -p 9200:9200 -e "discovery.type=single-node" -e "ES_JAVA_OPTS=-Xms1024m -Xmx1024m" -e "xpack.security.enabled=false" elasticsearch:8.11.1
```
As an alternative, you can go to [Elasticsearch integration GitHub](https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/elasticsearch) and start a Docker container running Elasticsearch using the provided `docker-compose.yml`:
```shell
docker compose up
```
Once you have a running Elasticsearch instance, install the `elasticsearch-haystack` integration:
```shell
pip install elasticsearch-haystack
```
## Usage
### On its own
```python
from haystack import Document
from haystack_integrations.components.retrievers.elasticsearch import (
ElasticsearchBM25Retriever,
)
from haystack_integrations.document_stores.elasticsearch import (
ElasticsearchDocumentStore,
)
from elasticsearch import Elasticsearch
document_store = ElasticsearchDocumentStore(hosts="http://localhost:9200/")
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
document_store.write_documents(documents=documents)
retriever = ElasticsearchBM25Retriever(document_store=document_store)
retriever.run(query="How many languages are spoken around the world today?")
```
### In a RAG pipeline
Set your `OPENAI_API_KEY` as an environment variable and then run the following code:
```python
from haystack_integrations.components.retrievers.elasticsearch import (
ElasticsearchBM25Retriever,
)
from haystack_integrations.document_stores.elasticsearch import (
ElasticsearchDocumentStore,
)
from elasticsearch import Elasticsearch
from haystack import Document
from haystack import Pipeline
from haystack.components.builders.answer_builder import AnswerBuilder
from haystack.components.builders.prompt_builder import PromptBuilder
from haystack.components.generators import OpenAIGenerator
from haystack.document_stores.types import DuplicatePolicy
import os
api_key = os.environ["OPENAI_API_KEY"]
## Create a RAG query pipeline
prompt_template = """
Given these documents, answer the question.\nDocuments:
{% for doc in documents %}
{{ doc.content }}
{% endfor %}
\nQuestion: {{question}}
\nAnswer:
"""
document_store = ElasticsearchDocumentStore(hosts="http://localhost:9200/")
## Add Documents
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
## DuplicatePolicy.SKIP param is optional, but useful to run the script multiple times without throwing errors
document_store.write_documents(documents=documents, policy=DuplicatePolicy.SKIP)
retriever = ElasticsearchBM25Retriever(document_store=document_store)
rag_pipeline = Pipeline()
rag_pipeline.add_component(name="retriever", instance=retriever)
rag_pipeline.add_component(
instance=PromptBuilder(template=prompt_template),
name="prompt_builder",
)
rag_pipeline.add_component(instance=OpenAIGenerator(api_key=api_key), name="llm")
rag_pipeline.add_component(instance=AnswerBuilder(), name="answer_builder")
rag_pipeline.connect("retriever", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder", "llm")
rag_pipeline.connect("llm.replies", "answer_builder.replies")
rag_pipeline.connect("llm.meta", "answer_builder.meta")
rag_pipeline.connect("retriever", "answer_builder.documents")
question = "How many languages are spoken around the world today?"
result = rag_pipeline.run(
{
"retriever": {"query": question},
"prompt_builder": {"question": question},
"answer_builder": {"query": question},
},
)
print(result["answer_builder"]["answers"][0].data)
```
Heres an example output you might get:
```python
"Over 7,000 languages are spoken around the world today"
```
@@ -0,0 +1,125 @@
---
title: "ElasticsearchEmbeddingRetriever"
id: elasticsearchembeddingretriever
slug: "/elasticsearchembeddingretriever"
description: "An embedding-based Retriever compatible with the Elasticsearch Document Store."
---
# ElasticsearchEmbeddingRetriever
An embedding-based Retriever compatible with the Elasticsearch Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of [ElasticsearchDocumentStore](../../document-stores/elasticsearch-document-store.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents |
| **API reference** | [Elasticsearch](/reference/integrations-elasticsearch) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/elasticsearch |
</div>
## Overview
The `ElasticsearchEmbeddingRetriever` is an embedding-based Retriever compatible with the `ElasticsearchDocumentStore`. It compares the query and Document embeddings and fetches the Documents most relevant to the query from the `ElasticsearchDocumentStore` based on the outcome.
When using the `ElasticsearchEmbeddingRetriever` in your NLP system, ensure it has the query and Document embeddings available. You can do so by adding a Document Embedder to your indexing pipeline and a Text Embedder to your query pipeline.
In addition to the `query_embedding`, the `ElasticsearchEmbeddingRetriever` accepts other optional parameters, including `top_k` (the maximum number of Documents to retrieve) and `filters` to narrow down the search space.
When initializing Retriever, you can also set `num_candidates`: the number of approximate nearest neighbor candidates on each shard. It's an advanced setting you can read more about in the [Elasticsearch documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/knn-search.html#tune-approximate-knn-for-speed-accuracy).
The `embedding_similarity_function` to use for embedding retrieval must be defined when the corresponding `ElasticsearchDocumentStore` is initialized.
## Installation
[Install](https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html) Elasticsearch and then [start](https://www.elastic.co/guide/en/elasticsearch/reference/current/starting-elasticsearch.html) an instance. Haystack supports Elasticsearch 8.
If you have Docker set up, we recommend pulling the Docker image and running it.
```shell
docker pull docker.elastic.co/elasticsearch/elasticsearch:8.11.1
docker run -p 9200:9200 -e "discovery.type=single-node" -e "ES_JAVA_OPTS=-Xms1024m -Xmx1024m" -e "xpack.security.enabled=false" elasticsearch:8.11.1
```
As an alternative, you can go to [Elasticsearch integration GitHub](https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/elasticsearch) and start a Docker container running Elasticsearch using the provided `docker-compose.yml`:
```shell
docker compose up
```
Once you have a running Elasticsearch instance, install the `elasticsearch-haystack` integration:
```shell
pip install elasticsearch-haystack
```
## Usage
### In a pipeline
Use this Retriever in a query Pipeline like this:
```python
from haystack_integrations.components.retrievers.elasticsearch import (
ElasticsearchEmbeddingRetriever,
)
from haystack_integrations.document_stores.elasticsearch import (
ElasticsearchDocumentStore,
)
from haystack.document_stores.types import DuplicatePolicy
from haystack import Document, Pipeline
from haystack.components.embedders import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
document_store = ElasticsearchDocumentStore(hosts="http://localhost:9200/")
model = "BAAI/bge-large-en-v1.5"
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
document_embedder = SentenceTransformersDocumentEmbedder(model=model)
documents_with_embeddings = document_embedder.run(documents)
document_store.write_documents(
documents_with_embeddings.get("documents"),
policy=DuplicatePolicy.SKIP,
)
query_pipeline = Pipeline()
query_pipeline.add_component(
"text_embedder",
SentenceTransformersTextEmbedder(model=model),
)
query_pipeline.add_component(
"retriever",
ElasticsearchEmbeddingRetriever(document_store=document_store),
)
query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
query = "How many languages are there?"
result = query_pipeline.run({"text_embedder": {"text": query}})
print(result["retriever"]["documents"][0])
```
The example output would be:
```python
Document(id=cfe93bc1c274908801e6670440bf2bbba54fad792770d57421f85ffa2a4fcc94, content: 'There are over 7,000 languages spoken around the world today.', score: 0.87717235, embedding: vector of size 1024)
```
@@ -0,0 +1,97 @@
---
title: "FAISSEmbeddingRetriever"
id: faissembeddingretriever
slug: "/faissembeddingretriever"
description: "An embedding-based Retriever compatible with the FAISSDocumentStore."
---
# FAISSEmbeddingRetriever
An embedding-based Retriever compatible with the FAISSDocumentStore.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in a semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [`FAISSDocumentStore`](../../document-stores/faissdocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A vector representing the query (a list of floats) |
| **Output variables** | `documents`: A list of documents |
| **API reference** | [FAISS](/reference/integrations-faiss) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/faiss |
</div>
## Overview
The `FAISSEmbeddingRetriever` is an embedding-based Retriever that queries a `FAISSDocumentStore`. It compares the query embedding to document embeddings stored in FAISS and returns the most similar documents.
This Retriever expects precomputed embeddings in the Document Store and a query embedding at runtime. You can generate them with a Document Embedder in your indexing pipeline and a Text Embedder in your query pipeline.
In addition to `query_embedding`, you can pass:
- `top_k`: The maximum number of documents to return.
- `filters`: Metadata filters to restrict retrieved documents.
You can also configure default filters and `filter_policy` at initialization.
## Usage
### On its own
```python
from haystack_integrations.document_stores.faiss import FAISSDocumentStore
from haystack_integrations.components.retrievers.faiss import FAISSEmbeddingRetriever
document_store = FAISSDocumentStore(embedding_dim=768)
retriever = FAISSEmbeddingRetriever(document_store=document_store, top_k=5)
# Example query embedding
result = retriever.run(query_embedding=[0.1] * 768)
print(result["documents"])
```
### In a pipeline
```python
from haystack import Document, Pipeline
from haystack.components.embedders import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
from haystack.document_stores.types import DuplicatePolicy
from haystack_integrations.document_stores.faiss import FAISSDocumentStore
from haystack_integrations.components.retrievers.faiss import FAISSEmbeddingRetriever
document_store = FAISSDocumentStore(embedding_dim=768)
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of intelligence.",
),
Document(
content="In certain places, you can witness the phenomenon of bioluminescent waves.",
),
]
document_embedder = SentenceTransformersDocumentEmbedder()
documents_with_embeddings = document_embedder.run(documents)["documents"]
document_store.write_documents(
documents_with_embeddings,
policy=DuplicatePolicy.OVERWRITE,
)
query_pipeline = Pipeline()
query_pipeline.add_component("text_embedder", SentenceTransformersTextEmbedder())
query_pipeline.add_component(
"retriever",
FAISSEmbeddingRetriever(document_store=document_store),
)
query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
query = "How many languages are there?"
result = query_pipeline.run({"text_embedder": {"text": query}})
print(result["retriever"]["documents"][0])
```
@@ -0,0 +1,127 @@
---
title: "FilterRetriever"
id: filterretriever
slug: "/filterretriever"
description: "Use this Retriever with any Document Store to get the Documents that match specific filters."
---
# FilterRetriever
Use this Retriever with any Document Store to get the Documents that match specific filters.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | At the beginning of a Pipeline |
| **Mandatory init variables** | `document_store`: An instance of a Document Store |
| **Mandatory run variables** | `filters`: A dictionary of filters in the same syntax supported by the Document Stores |
| **Output variables** | `documents`: All the documents that match these filters |
| **API reference** | [Retrievers](/reference/retrievers-api) |
| **GitHub link** | https://github.com/deepset-ai/haystack/blob/main/haystack/components/retrievers/filter_retriever.py |
</div>
## Overview
`FilterRetriever` retrieves Documents that match the provided filters.
Its a special kind of Retriever it can work with all Document Stores instead of being specialized to work with only one.
However, as every other Retriever, it needs some Document Store at initialization time, and it will perform filtering on the content of that instance only.
Therefore, it can be used as any other Retriever in a Pipeline.
Pay attention when using `FilterRetriever` on a Document Store that contains many Documents, as `FilterRetriever` will return all documents that match the filters. The `run` command with no filters can easily overwhelm other components in the Pipeline (for example, Generators):
```python
filter_retriever.run({})
```
Another thing to note is that `FilterRetriever` does not score your Documents or rank them in any way. If you need to rank the Documents by similarity to a query, consider using Ranker components.
## Usage
### On its own
```python
from haystack import Document
from haystack.components.retrievers import FilterRetriever
from haystack.document_stores.in_memory import InMemoryDocumentStore
docs = [
Document(content="Python is a popular programming language", meta={"lang": "en"}),
Document(
content="python ist eine beliebte Programmiersprache",
meta={"lang": "de"},
),
]
doc_store = InMemoryDocumentStore()
doc_store.write_documents(docs)
retriever = FilterRetriever(doc_store)
result = retriever.run(filters={"field": "lang", "operator": "==", "value": "en"})
assert "documents" in result
assert len(result["documents"]) == 1
assert result["documents"][0].content == "Python is a popular programming language"
```
### In a RAG pipeline
Set your `OPENAI_API_KEY` as an environment variable and then run the following code:
```python
from haystack.components.retrievers.filter_retriever import FilterRetriever
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack import Document, Pipeline
from haystack.components.builders.answer_builder import AnswerBuilder
from haystack.components.builders.prompt_builder import PromptBuilder
from haystack.components.generators import OpenAIGenerator
from haystack.document_stores.types import DuplicatePolicy
import os
api_key = os.environ['OPENAI_API_KEY']
document_store = InMemoryDocumentStore()
documents = [
Document(content="Mark lives in Berlin.", meta={"year": 2018}),
Document(content="Mark lives in Paris.", meta={"year": 2021}),
Document(content="Mark is Danish.", meta={"year": 2021}),
Document(content="Mark lives in New York.", meta={"year": 2023}),
]
document_store.write_documents(documents=documents)
## Create a RAG query pipeline
prompt_template = """
Given these documents, answer the question.\nDocuments:
{% for doc in documents %}
{{ doc.content }}
{% endfor %}
\nQuestion: {{question}}
\nAnswer:
"""
rag_pipeline = Pipeline()
rag_pipeline.add_component(name="retriever", instance=FilterRetriever(document_store=document_store))
rag_pipeline.add_component(instance=PromptBuilder(template=prompt_template), name="prompt_builder")
rag_pipeline.add_component(instance=OpenAIGenerator(api_key=api_key), name="llm")
rag_pipeline.connect("retriever", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder", "llm")
result = rag_pipeline.run(
{
"retriever": {"filters": {"field": "year", "operator": "==", "value": 2021}},
"prompt_builder": {"question": "Where does Mark live?"},
}
)
print(result['answer_builder']['answers'][0])`
```
Heres an example output you might get:
```
According to the provided documents, Mark lives in Paris.
```
@@ -0,0 +1,165 @@
---
title: "InMemoryBM25Retriever"
id: inmemorybm25retriever
slug: "/inmemorybm25retriever"
description: "A keyword-based Retriever compatible with InMemoryDocumentStore."
---
# InMemoryBM25Retriever
A keyword-based Retriever compatible with InMemoryDocumentStore.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | In query pipelines: <br />In a RAG pipeline, before a [`PromptBuilder`](../builders/promptbuilder.mdx) <br />In a semantic search pipeline, as the last component <br />In an extractive QA pipeline, before an [`ExtractiveReader`](../readers/extractivereader.mdx) |
| **Mandatory init variables** | `document_store`: An instance of [InMemoryDocumentStore](../../document-stores/inmemorydocumentstore.mdx) |
| **Mandatory run variables** | `query`: A query string |
| **Output variables** | `documents`: A list of documents (matching the query) |
| **API reference** | [Retrievers](/reference/retrievers-api) |
| **GitHub link** | https://github.com/deepset-ai/haystack/blob/main/haystack/components/retrievers/in_memory/bm25_retriever.py |
</div>
## Overview
`InMemoryBM25Retriever` is a keyword-based Retriever that fetches Documents matching a query from a temporary in-memory database. It determines the similarity between Documents and the query based on the BM25 algorithm, which computes a weighted word overlap between the two strings.
Since the `InMemoryBM25Retriever` matches strings based on word overlap, its often used to find exact matches to names of persons or products, IDs, or well-defined error messages. The BM25 algorithm is very lightweight and simple. Nevertheless, it can be hard to beat with more complex embedding-based approaches on out-of-domain data.
In addition to the `query`, the `InMemoryBM25Retriever` accepts other optional parameters, including `top_k` (the maximum number of Documents to retrieve) and `filters` to narrow down the search space.
Some relevant parameters that impact the BM25 retrieval must be defined when the corresponding `InMemoryDocumentStore` is initialized: these include the specific BM25 algorithm and its parameters.
## Usage
### On its own
```python
from haystack import Document
from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
from haystack.document_stores.in_memory import InMemoryDocumentStore
document_store = InMemoryDocumentStore()
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
document_store.write_documents(documents=documents)
retriever = InMemoryBM25Retriever(document_store=document_store)
retriever.run(query="How many languages are spoken around the world today?")
```
### In a Pipeline
#### In a RAG Pipeline
Here's an example of the Retriever in a retrieval-augmented generation pipeline:
```python
import os
from haystack import Document
from haystack import Pipeline
from haystack.components.builders.answer_builder import AnswerBuilder
from haystack.components.builders.prompt_builder import PromptBuilder
from haystack.components.generators import OpenAIGenerator
from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
from haystack.document_stores.in_memory import InMemoryDocumentStore
## Create a RAG query pipeline
prompt_template = """
Given these documents, answer the question.\nDocuments:
{% for doc in documents %}
{{ doc.content }}
{% endfor %}
\nQuestion: {{question}}
\nAnswer:
"""
os.environ["OPENAI_API_KEY"] = "sk-XXXXXX"
rag_pipeline = Pipeline()
rag_pipeline.add_component(
instance=InMemoryBM25Retriever(document_store=InMemoryDocumentStore()),
name="retriever",
)
rag_pipeline.add_component(
instance=PromptBuilder(template=prompt_template),
name="prompt_builder",
)
rag_pipeline.add_component(instance=OpenAIGenerator(), name="llm")
rag_pipeline.add_component(instance=AnswerBuilder(), name="answer_builder")
rag_pipeline.connect("retriever", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder", "llm")
rag_pipeline.connect("llm.replies", "answer_builder.replies")
rag_pipeline.connect("llm.metadata", "answer_builder.metadata")
rag_pipeline.connect("retriever", "answer_builder.documents")
## Draw the pipeline
rag_pipeline.draw("./rag_pipeline.png")
## Add Documents
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
rag_pipeline.get_component("retriever").document_store.write_documents(documents)
## Run the pipeline
question = "How many languages are there?"
result = rag_pipeline.run(
{
"retriever": {"query": question},
"prompt_builder": {"question": question},
"answer_builder": {"query": question},
},
)
print(result["answer_builder"]["answers"][0])
```
#### In a Document Search Pipeline
Here's how you can use this Retriever in a document search pipeline:
```python
from haystack import Document
from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.pipeline import Pipeline
## Create components and a query pipeline
document_store = InMemoryDocumentStore()
retriever = InMemoryBM25Retriever(document_store=document_store)
pipeline = Pipeline()
pipeline.add_component(instance=retriever, name="retriever")
## Add Documents
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
document_store.write_documents(documents)
## Run the pipeline
result = pipeline.run(data={"retriever": {"query": "How many languages are there?"}})
print(result["retriever"]["documents"][0])
```
@@ -0,0 +1,80 @@
---
title: "InMemoryEmbeddingRetriever"
id: inmemoryembeddingretriever
slug: "/inmemoryembeddingretriever"
description: "Use this Retriever with the InMemoryDocumentStore if you're looking for embedding-based retrieval."
---
# InMemoryEmbeddingRetriever
Use this Retriever with the InMemoryDocumentStore if you're looking for embedding-based retrieval.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | In query pipelines: <br />In a RAG pipeline, before a [`PromptBuilder`](../builders/promptbuilder.mdx) <br />In a semantic search pipeline, as the last component <br />In an extractive QA pipeline, after a Tex tEmbedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) |
| **Mandatory init variables** | `document_store`: An instance of [InMemoryDocumentStore](../../document-stores/inmemorydocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floating point numbers |
| **Output variables** | `documents`: A list of documents |
| **API reference** | [Retrievers](/reference/retrievers-api) |
| **GitHub link** | https://github.com/deepset-ai/haystack/blob/main/haystack/components/retrievers/in_memory/embedding_retriever.py |
</div>
## Overview
The `InMemoryEmbeddingRetriever` is an embedding-based Retriever compatible with the `InMemoryDocumentStore`. It compares the query and Document embeddings and fetches the Documents most relevant to the query from the `InMemoryDocumentStore` based on the outcome.
When using the `InMemoryEmbeddingRetriever` in your NLP system, make sure it has the query and Document embeddings available. You can do so by adding a DocumentEmbedder to your indexing pipeline and a Text Embedder to your query pipeline. For details, see [Embedders](../embedders.mdx).
In addition to the `query_embedding`, the `InMemoryEmbeddingRetriever` accepts other optional parameters, including `top_k` (the maximum number of Documents to retrieve) and `filters` to narrow down the search space.
The `embedding_similarity_function` to use for embedding retrieval must be defined when the corresponding`InMemoryDocumentStore` is initialized.
## Usage
### In a pipeline
Use this Retriever in a query pipeline like this:
```python
from haystack import Document, Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.embedders import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
from haystack.components.retrievers import InMemoryEmbeddingRetriever
document_store = InMemoryDocumentStore(embedding_similarity_function="cosine")
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
document_embedder = SentenceTransformersDocumentEmbedder()
documents_with_embeddings = document_embedder.run(documents)["documents"]
document_store.write_documents(documents_with_embeddings)
query_pipeline = Pipeline()
query_pipeline.add_component("text_embedder", SentenceTransformersTextEmbedder())
query_pipeline.add_component(
"retriever",
InMemoryEmbeddingRetriever(document_store=document_store),
)
query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
query = "How many languages are there?"
result = query_pipeline.run({"text_embedder": {"text": query}})
print(result["retriever"]["documents"][0])
```
@@ -0,0 +1,142 @@
---
title: "MongoDBAtlasEmbeddingRetriever"
id: mongodbatlasembeddingretriever
slug: "/mongodbatlasembeddingretriever"
description: "This is an embedding Retriever compatible with the MongoDB Atlas Document Store."
---
# MongoDBAtlasEmbeddingRetriever
This is an embedding Retriever compatible with the MongoDB Atlas Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [MongoDBAtlasDocumentStore](../../document-stores/mongodbatlasdocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents |
| **API reference** | [MongoDB Atlas](/reference/integrations-mongodb-atlas) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/mongodb_atlas |
</div>
The `MongoDBAtlasEmbeddingRetriever` is an embedding-based Retriever compatible with the [`MongoDBAtlasDocumentStore`](../../document-stores/mongodbatlasdocumentstore.mdx). It compares the query and Document embeddings and fetches the Documents most relevant to the query from the Document Store based on the outcome.
### Parameters
When using the `MongoDBAtlasEmbeddingRetriever` in your NLP system, ensure the query and Document [embeddings](../embedders.mdx) are available. You can do so by adding a Document Embedder to your indexing Pipeline and a Text Embedder to your query Pipeline.
In addition to the `query_embedding`, the `MongoDBAtlasEmbeddingRetriever` accepts other optional parameters, including `top_k` (the maximum number of Documents to retrieve) and `filters` to narrow down the search space.
## Usage
### Installation
To start using MongoDB Atlas with Haystack, install the package with:
```shell
pip install mongodb-atlas-haystack
```
### On its own
The Retriever needs an instance of `MongoDBAtlasDocumentStore` and indexed Documents to run.
```python
from haystack_integrations.document_stores.mongodb_atlas import (
MongoDBAtlasDocumentStore,
)
from haystack_integrations.components.retrievers.mongodb_atlas import (
MongoDBAtlasEmbeddingRetriever,
)
document_store = MongoDBAtlasDocumentStore()
retriever = MongoDBAtlasEmbeddingRetriever(document_store=document_store)
## example run query
retriever.run(query_embedding=[0.1] * 384)
```
### In a Pipeline
```python
from haystack import Pipeline, Document
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.writers import DocumentWriter
from haystack.components.generators import OpenAIGenerator
from haystack.components.builders.prompt_builder import PromptBuilder
from haystack.components.embedders import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
from haystack_integrations.document_stores.mongodb_atlas import (
MongoDBAtlasDocumentStore,
)
from haystack_integrations.components.embedders.mongodb_atlas import (
MongoDBAtlasEmbeddingRetriever,
)
## Create some example documents
documents = [
Document(content="My name is Jean and I live in Paris."),
Document(content="My name is Mark and I live in Berlin."),
Document(content="My name is Giorgio and I live in Rome."),
]
## We support many different databases. Here we load a simple and lightweight in-memory document store.
document_store = MongoDBAtlasDocumentStore()
## Define some more components
doc_writer = DocumentWriter(document_store=document_store, policy=DuplicatePolicy.SKIP)
doc_embedder = SentenceTransformersDocumentEmbedder(model="intfloat/e5-base-v2")
query_embedder = SentenceTransformersTextEmbedder(model="intfloat/e5-base-v2")
## Pipeline that ingests document for retrieval
ingestion_pipe = Pipeline()
ingestion_pipe.add_component(instance=doc_embedder, name="doc_embedder")
ingestion_pipe.add_component(instance=doc_writer, name="doc_writer")
ingestion_pipe.connect("doc_embedder.documents", "doc_writer.documents")
ingestion_pipe.run({"doc_embedder": {"documents": documents}})
## Build a RAG pipeline with a Retriever to get relevant documents to
## the query and a OpenAIGenerator interacting with LLMs using a custom prompt.
prompt_template = """
Given these documents, answer the question.\nDocuments:
{% for doc in documents %}
{{ doc.content }}
{% endfor %}
\nQuestion: {{question}}
\nAnswer:
"""
rag_pipeline = Pipeline()
rag_pipeline.add_component(instance=query_embedder, name="query_embedder")
rag_pipeline.add_component(
instance=MongoDBAtlasEmbeddingRetriever(document_store=document_store),
name="retriever",
)
rag_pipeline.add_component(
instance=PromptBuilder(template=prompt_template),
name="prompt_builder",
)
rag_pipeline.add_component(instance=OpenAIGenerator(), name="llm")
rag_pipeline.connect("query_embedder", "retriever.query_embedding")
rag_pipeline.connect("embedding_retriever", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder", "llm")
## Ask a question on the data you just added.
question = "Where does Mark live?"
result = rag_pipeline.run(
{
"query_embedder": {"text": question},
"prompt_builder": {"question": question},
},
)
## For details, like which documents were used to generate the answer, look into the GeneratedAnswer object
print(result["answer_builder"]["answers"])
```
@@ -0,0 +1,153 @@
---
title: "MongoDBAtlasFullTextRetriever"
id: mongodbatlasfulltextretriever
slug: "/mongodbatlasfulltextretriever"
description: "This is a full-text search Retriever compatible with the MongoDB Atlas Document Store."
---
# MongoDBAtlasFullTextRetriever
This is a full-text search Retriever compatible with the MongoDB Atlas Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. Before a [ChatPromptBuilder](../builders/chatpromptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. Before an [ExtractiveReader](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [MongoDBAtlasDocumentStore](../../document-stores/mongodbatlasdocumentstore.mdx) |
| **Mandatory run variables** | `query`: A query string to search for. If the query contains multiple terms, Atlas Search evaluates each term separately for matches. |
| **Output variables** | `documents`: A list of documents |
| **API reference** | [MongoDB Atlas](/reference/integrations-mongodb-atlas) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/mongodb_atlas |
</div>
The `MongoDBAtlasFullTextRetriever` is a full-text search Retriever compatible with the [`MongoDBAtlasDocumentStore`](../../document-stores/mongodbatlasdocumentstore.mdx). The full-text search is dependent on the `full_text_search_index` used in the [`MongoDBAtlasDocumentStore`](../../document-stores/mongodbatlasdocumentstore.mdx).
### Parameters
In addition to the `query`, the `MongoDBAtlasFullTextRetriever` accepts other optional parameters, including `top_k` (the maximum number of Documents to retrieve) and `filters` to narrow down the search space.
When running the component, you can specify more optional parameters such as `fuzzy` or `synonyms`, `match_criteria`, `score`. Check out our [MongoDB Atlas](/reference/integrations-mongodb-atlas) API Reference for more details on all parameters.
## Usage
### Installation
To start using MongoDB Atlas with Haystack, install the package with:
```shell
pip install mongodb-atlas-haystack
```
### On its own
The Retriever needs an instance of `MongoDBAtlasDocumentStore` and indexed documents to run.
```python
from haystack_integrations.document_stores.mongodb_atlas import (
MongoDBAtlasDocumentStore,
)
from haystack_integrations.components.retrievers.mongodb_atlas import (
MongoDBAtlasFullTextRetriever,
)
store = MongoDBAtlasDocumentStore(
database_name="your_existing_db",
collection_name="your_existing_collection",
vector_search_index="your_existing_index",
full_text_search_index="your_existing_index",
)
retriever = MongoDBAtlasFullTextRetriever(document_store=store)
results = retriever.run(query="Your search query")
print(results["documents"])
```
### In a Pipeline
Here's a Hybrid Retrieval pipeline example that makes use of both available MongoDB Atlas Retrievers:
```python
from haystack import Pipeline, Document
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.writers import DocumentWriter
from haystack.components.embedders import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
from haystack.components.joiners import DocumentJoiner
from haystack_integrations.document_stores.mongodb_atlas import (
MongoDBAtlasDocumentStore,
)
from haystack_integrations.components.retrievers.mongodb_atlas import (
MongoDBAtlasEmbeddingRetriever,
MongoDBAtlasFullTextRetriever,
)
documents = [
Document(content="My name is Jean and I live in Paris."),
Document(content="My name is Mark and I live in Berlin."),
Document(content="My name is Giorgio and I live in Rome."),
Document(content="Python is a programming language popular for data science."),
Document(
content="MongoDB Atlas offers full-text search and vector search capabilities.",
),
]
document_store = MongoDBAtlasDocumentStore(
database_name="haystack_test",
collection_name="test_collection",
vector_search_index="test_vector_search_index",
full_text_search_index="test_full_text_search_index",
)
## Clean out any old data so this example is repeatable
print(f"Clearing collection {document_store.collection_name} …")
document_store.collection.delete_many({})
ingest_pipe = Pipeline()
doc_embedder = SentenceTransformersDocumentEmbedder(model="intfloat/e5-base-v2")
ingest_pipe.add_component(instance=doc_embedder, name="doc_embedder")
doc_writer = DocumentWriter(document_store=document_store, policy=DuplicatePolicy.SKIP)
ingest_pipe.add_component(instance=doc_writer, name="doc_writer")
ingest_pipe.connect("doc_embedder.documents", "doc_writer.documents")
print(f"Running ingestion on {len(documents)} in-memory docs …")
ingest_pipe.run({"doc_embedder": {"documents": documents}})
query_pipe = Pipeline()
text_embedder = SentenceTransformersTextEmbedder(model="intfloat/e5-base-v2")
query_pipe.add_component(instance=text_embedder, name="text_embedder")
embed_retriever = MongoDBAtlasEmbeddingRetriever(document_store=document_store, top_k=3)
query_pipe.add_component(instance=embed_retriever, name="embedding_retriever")
query_pipe.connect("text_embedder", "embedding_retriever")
## (c) full-text retriever
ft_retriever = MongoDBAtlasFullTextRetriever(document_store=document_store, top_k=3)
query_pipe.add_component(instance=ft_retriever, name="full_text_retriever")
joiner = DocumentJoiner(join_mode="reciprocal_rank_fusion", top_k=3)
query_pipe.add_component(instance=joiner, name="joiner")
query_pipe.connect("embedding_retriever", "joiner")
query_pipe.connect("full_text_retriever", "joiner")
question = "Where does Mark live?"
print(f"Running hybrid retrieval for query: '{question}'")
output = query_pipe.run(
{
"text_embedder": {"text": question},
"full_text_retriever": {"query": question},
},
)
print("\nFinal fused documents:")
for doc in output["joiner"]["documents"]:
print(f"- {doc.content}")
```
@@ -0,0 +1,150 @@
---
title: "MultiQueryEmbeddingRetriever"
id: multiqueryembeddingretriever
slug: "/multiqueryembeddingretriever"
description: "Retrieves documents using multiple queries in parallel with an embedding-based Retriever."
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# MultiQueryEmbeddingRetriever
Retrieves documents using multiple queries in parallel with an embedding-based Retriever.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | After a [`QueryExpander`](../query/queryexpander.mdx) component, before a [`ChatPromptBuilder`](../builders/chatpromptbuilder.mdx) in RAG pipelines |
| **Mandatory init variables** | `retriever`: An embedding-based Retriever (such as `InMemoryEmbeddingRetriever`)<br />`query_embedder`: A Text Embedder component |
| **Mandatory run variables** | `queries`: A list of query strings |
| **Output variables** | `documents`: A list of retrieved documents sorted by relevance score |
| **API reference** | [Retrievers](/reference/retrievers-api) |
| **GitHub link** | https://github.com/deepset-ai/haystack/blob/main/haystack/components/retrievers/multi_query_embedding_retriever.py |
</div>
## Overview
`MultiQueryEmbeddingRetriever` improves retrieval recall by searching for documents using multiple queries in parallel. Each query is converted to an embedding using a Text Embedder, and an embedding-based Retriever fetches relevant documents.
The component:
- Processes queries in parallel using a thread pool for better performance
- Automatically deduplicates results based on document content
- Sorts the final results by relevance score
This Retriever is particularly effective when combined with [`QueryExpander`](../query/queryexpander.mdx), which generates multiple query variations from a single user query. By searching with these variations, you can find documents that might not match the original query phrasing but are still relevant.
Use `MultiQueryEmbeddingRetriever` when your documents use different words than your users' queries, or when you want to find more diverse results in RAG pipelines. Running multiple queries takes more time, but you can speed it up by increasing `max_workers` to run queries in parallel.
:::tip[When to use a `MultiQueryTextRetriever` instead]
If you need exact keyword matching and don't want to use embeddings, use [`MultiQueryTextRetriever`](multiquerytextretriever.mdx) instead. It works with text-based Retrievers like `InMemoryBM25Retriever` and is better when synonyms can be generated through query expansion.
:::
### Passing Additional Retriever Parameters
You can pass additional parameters to the underlying Retriever using `retriever_kwargs`:
```python
result = multi_query_retriever.run(
queries=["renewable energy", "sustainable power"],
retriever_kwargs={"top_k": 5},
)
```
## Usage
This pipeline takes a single query "sustainable power generation" and expands it into multiple variations using an LLM (for example: "renewable energy sources", "green electricity", "clean power"). The Retriever then converts each variation to an embedding and searches for similar documents. This way, documents about "solar energy" or "wind energy" can be found even though they don't contain the words "sustainable power generation".
Before running the pipeline, documents must be embedded using a Document Embedder and stored in the Document Store.
<Tabs>
<TabItem value="python" label="Python" default>
```python
from haystack import Document, Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.embedders import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
from haystack.components.retrievers import (
InMemoryEmbeddingRetriever,
MultiQueryEmbeddingRetriever,
)
from haystack.components.query import QueryExpander
documents = [
Document(
content="Renewable energy is energy that is collected from renewable resources.",
),
Document(
content="Solar energy is a type of green energy that is harnessed from the sun.",
),
Document(
content="Wind energy is another type of green energy that is generated by wind turbines.",
),
Document(
content="Geothermal energy is heat that comes from the sub-surface of the earth.",
),
]
doc_store = InMemoryDocumentStore()
doc_embedder = SentenceTransformersDocumentEmbedder(
model="sentence-transformers/all-MiniLM-L6-v2",
)
documents_with_embeddings = doc_embedder.run(documents)["documents"]
doc_store.write_documents(documents_with_embeddings)
pipeline = Pipeline()
pipeline.add_component("query_expander", QueryExpander(n_expansions=3))
pipeline.add_component(
"retriever",
MultiQueryEmbeddingRetriever(
retriever=InMemoryEmbeddingRetriever(document_store=doc_store, top_k=2),
query_embedder=SentenceTransformersTextEmbedder(
model="sentence-transformers/all-MiniLM-L6-v2",
),
),
)
pipeline.connect("query_expander.queries", "retriever.queries")
result = pipeline.run({"query_expander": {"query": "sustainable power generation"}})
for doc in result["retriever"]["documents"]:
print(f"Score: {doc.score:.3f} | {doc.content}")
```
</TabItem>
<TabItem value="yaml" label="YAML">
```yaml
components:
query_expander:
type: haystack.components.query.query_expander.QueryExpander
init_parameters:
n_expansions: 3
retriever:
type: haystack.components.retrievers.multi_query_embedding_retriever.MultiQueryEmbeddingRetriever
init_parameters:
retriever:
type: haystack.components.retrievers.in_memory.embedding_retriever.InMemoryEmbeddingRetriever
init_parameters:
document_store:
type: haystack.document_stores.in_memory.document_store.InMemoryDocumentStore
init_parameters: {}
top_k: 2
query_embedder:
type: haystack.components.embedders.sentence_transformers_text_embedder.SentenceTransformersTextEmbedder
init_parameters:
model: sentence-transformers/all-MiniLM-L6-v2
connections:
- sender: query_expander.queries
receiver: retriever.queries
```
</TabItem>
</Tabs>
@@ -0,0 +1,307 @@
---
title: "MultiQueryTextRetriever"
id: multiquerytextretriever
slug: "/multiquerytextretriever"
description: "Retrieves documents using multiple queries in parallel with a text-based Retriever."
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# MultiQueryTextRetriever
Retrieves documents using multiple queries in parallel with a text-based Retriever.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | After a [`QueryExpander`](../query/queryexpander.mdx) component, before a [`ChatPromptBuilder`](../builders/chatpromptbuilder.mdx) in RAG pipelines |
| **Mandatory init variables** | `retriever`: A text-based Retriever (such as `InMemoryBM25Retriever`) |
| **Mandatory run variables** | `queries`: A list of query strings |
| **Output variables** | `documents`: A list of retrieved documents sorted by relevance score |
| **API reference** | [Retrievers](/reference/retrievers-api) |
| **GitHub link** | https://github.com/deepset-ai/haystack/blob/main/haystack/components/retrievers/multi_query_text_retriever.py |
</div>
## Overview
`MultiQueryTextRetriever` improves retrieval recall by searching for documents using multiple queries in parallel. It wraps a text-based Retriever (such as `InMemoryBM25Retriever`) and processes multiple query strings simultaneously using a thread pool.
The component:
- Processes queries in parallel for better performance
- Automatically deduplicates results based on document content
- Sorts the final results by relevance score
This Retriever is particularly effective when combined with [`QueryExpander`](../query/queryexpander.mdx), which generates multiple query variations from a single user query. By searching with these variations, you can find documents that use different keywords than the original query.
Use `MultiQueryTextRetriever` when your documents use different words than your users' queries, or when you want to use query expansion with keyword-based search (BM25). Running multiple queries takes more time, but you can speed it up by increasing `max_workers` to run queries in parallel.
:::tip[When to use `MultiQueryEmbeddingRetriever` instead]
If you need semantic search where meaning matters more than exact keyword matches, use [`MultiQueryEmbeddingRetriever`](multiqueryembeddingretriever.mdx) instead. It works with embedding-based Retrievers and requires a Text Embedder.
:::
### Passing Additional Retriever Parameters
You can pass additional parameters to the underlying Retriever using `retriever_kwargs`:
```python
result = multiquery_retriever.run(
queries=["renewable energy", "sustainable power"],
retriever_kwargs={"top_k": 5},
)
```
## Usage
### On its own
In this example, we pass three queries manually to the Retriever: "renewable energy", "geothermal", and "hydropower". The Retriever runs a BM25 search for each query (retrieving up to 2 documents per query), then combines all results, removes duplicates, and sorts them by score.
```python
from haystack import Document
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.retrievers import (
InMemoryBM25Retriever,
MultiQueryTextRetriever,
)
documents = [
Document(
content="Renewable energy is energy that is collected from renewable resources.",
),
Document(
content="Solar energy is a type of green energy that is harnessed from the sun.",
),
Document(
content="Wind energy is another type of green energy that is generated by wind turbines.",
),
Document(
content="Hydropower is a form of renewable energy using the flow of water to generate electricity.",
),
Document(
content="Geothermal energy is heat that comes from the sub-surface of the earth.",
),
]
document_store = InMemoryDocumentStore()
document_store.write_documents(documents)
retriever = MultiQueryTextRetriever(
retriever=InMemoryBM25Retriever(document_store=document_store, top_k=2),
)
results = retriever.run(queries=["renewable energy", "geothermal", "hydropower"])
for doc in results["documents"]:
print(f"Content: {doc.content}, Score: {doc.score:.4f}")
```
### In a pipeline with QueryExpander
This pipeline takes a single query "sustainable power" and expands it into multiple variations using an LLM (for example: "renewable energy sources", "green electricity", "clean power"). The Retriever then searches for each variation and combines the results. This way, documents about "solar energy" or "hydropower" can be found even though they don't contain the words "sustainable power".
<Tabs>
<TabItem value="python" label="Python" default>
```python
from haystack import Document, Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.query import QueryExpander
from haystack.components.retrievers import (
InMemoryBM25Retriever,
MultiQueryTextRetriever,
)
documents = [
Document(
content="Renewable energy is energy that is collected from renewable resources.",
),
Document(
content="Solar energy is a type of green energy that is harnessed from the sun.",
),
Document(
content="Wind energy is another type of green energy that is generated by wind turbines.",
),
Document(
content="Hydropower is a form of renewable energy using the flow of water to generate electricity.",
),
Document(
content="Geothermal energy is heat that comes from the sub-surface of the earth.",
),
]
document_store = InMemoryDocumentStore()
document_store.write_documents(documents)
pipeline = Pipeline()
pipeline.add_component("query_expander", QueryExpander(n_expansions=3))
pipeline.add_component(
"retriever",
MultiQueryTextRetriever(
retriever=InMemoryBM25Retriever(document_store=document_store, top_k=2),
),
)
pipeline.connect("query_expander.queries", "retriever.queries")
result = pipeline.run({"query_expander": {"query": "sustainable power"}})
for doc in result["retriever"]["documents"]:
print(f"Score: {doc.score:.3f} | {doc.content}")
```
</TabItem>
<TabItem value="yaml" label="YAML">
```yaml
components:
query_expander:
type: haystack.components.query.query_expander.QueryExpander
init_parameters:
n_expansions: 3
retriever:
type: haystack.components.retrievers.multi_query_text_retriever.MultiQueryTextRetriever
init_parameters:
retriever:
type: haystack.components.retrievers.in_memory.bm25_retriever.InMemoryBM25Retriever
init_parameters:
document_store:
type: haystack.document_stores.in_memory.document_store.InMemoryDocumentStore
init_parameters: {}
top_k: 2
connections:
- sender: query_expander.queries
receiver: retriever.queries
```
</TabItem>
</Tabs>
### In a RAG pipeline
This RAG pipeline answers questions using query expansion. When a user asks "What types of energy come from natural sources?", the pipeline:
1. Expands the question into multiple search queries using an LLM
2. Retrieves relevant documents for each query variation
3. Builds a prompt containing the retrieved documents and the original question
4. Sends the prompt to an LLM to generate an answer
The question is sent to both the `query_expander` (for generating search queries) and the `prompt_builder` (for the final prompt to the LLM).
<Tabs>
<TabItem value="python" label="Python" default>
```python
from haystack import Document, Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.builders import ChatPromptBuilder
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.query import QueryExpander
from haystack.components.retrievers import (
InMemoryBM25Retriever,
MultiQueryTextRetriever,
)
from haystack.dataclasses import ChatMessage
documents = [
Document(
content="Renewable energy is energy that is collected from renewable resources.",
),
Document(
content="Solar energy is a type of green energy that is harnessed from the sun.",
),
Document(
content="Wind energy is another type of green energy that is generated by wind turbines.",
),
]
document_store = InMemoryDocumentStore()
document_store.write_documents(documents)
prompt_template = [
ChatMessage.from_system(
"You are a helpful assistant that answers questions based on the provided documents.",
),
ChatMessage.from_user(
"Given these documents, answer the question.\n"
"Documents:\n"
"{% for doc in documents %}"
"{{ doc.content }}\n"
"{% endfor %}\n"
"Question: {{ question }}",
),
]
# Note: This assumes OPENAI_API_KEY environment variable is set
rag_pipeline = Pipeline()
rag_pipeline.add_component("query_expander", QueryExpander(n_expansions=2))
rag_pipeline.add_component(
"retriever",
MultiQueryTextRetriever(
retriever=InMemoryBM25Retriever(document_store=document_store, top_k=2),
),
)
rag_pipeline.add_component(
"prompt_builder",
ChatPromptBuilder(
template=prompt_template,
required_variables=["documents", "question"],
),
)
rag_pipeline.add_component("llm", OpenAIChatGenerator())
rag_pipeline.connect("query_expander.queries", "retriever.queries")
rag_pipeline.connect("retriever.documents", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder.prompt", "llm.messages")
question = "What types of energy come from natural sources?"
result = rag_pipeline.run(
{"query_expander": {"query": question}, "prompt_builder": {"question": question}},
)
print(result["llm"]["replies"][0].text)
```
</TabItem>
<TabItem value="yaml" label="YAML">
```yaml
components:
query_expander:
type: haystack.components.query.query_expander.QueryExpander
init_parameters:
n_expansions: 2
retriever:
type: haystack.components.retrievers.multi_query_text_retriever.MultiQueryTextRetriever
init_parameters:
retriever:
type: haystack.components.retrievers.in_memory.bm25_retriever.InMemoryBM25Retriever
init_parameters:
document_store:
type: haystack.document_stores.in_memory.document_store.InMemoryDocumentStore
init_parameters: {}
top_k: 2
prompt_builder:
type: haystack.components.builders.chat_prompt_builder.ChatPromptBuilder
init_parameters:
required_variables:
- documents
- question
llm:
type: haystack.components.generators.chat.openai.OpenAIChatGenerator
init_parameters: {}
connections:
- sender: query_expander.queries
receiver: retriever.queries
- sender: retriever.documents
receiver: prompt_builder.documents
- sender: prompt_builder.prompt
receiver: llm.messages
```
</TabItem>
</Tabs>
@@ -0,0 +1,159 @@
---
title: "OpenSearchBM25Retriever"
id: opensearchbm25retriever
slug: "/opensearchbm25retriever"
description: "This is a keyword-based Retriever that fetches Documents matching a query from an OpenSearch Document Store."
---
# OpenSearchBM25Retriever
This is a keyword-based Retriever that fetches Documents matching a query from an OpenSearch Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. Before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. Before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of an [OpenSearchDocumentStore](../../document-stores/opensearch-document-store.mdx) |
| **Mandatory run variables** | `query`: A query string |
| **Output variables** | `documents`: A list of documents matching the query |
| **API reference** | [OpenSearch](/reference/integrations-opensearch) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/opensearch |
</div>
## Overview
`OpenSearchBM25Retriever` is a keyword-based Retriever that fetches Documents matching a query from an `OpenSearchDocumentStore`. It determines the similarity between Documents and the query based on the BM25 algorithm, which computes a weighted word overlap between the two strings.
Since the `OpenSearchBM25Retriever` matches strings based on word overlap, its often used to find exact matches to names of persons or products, IDs, or well-defined error messages. The BM25 algorithm is very lightweight and simple. Nevertheless, it can be hard to beat with more complex embedding-based approaches on out-of-domain data.
In addition to the `query`, the `OpenSearchBM25Retriever` accepts other optional parameters, including `top_k` (the maximum number of Documents to retrieve) and `filters` to narrow down the search space.
You can adjust how [inexact fuzzy matching](https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#fuzziness) is performed, using the `fuzziness` parameter.
It is also possible to specify if all terms in the query must match using the `all_terms_must_match` parameter, which defaults to `False`.
If you want more flexible matching of a query to Documents, you can use the `OpenSearchEmbeddingRetriever`, which uses vectors created by LLMs to retrieve relevant information.
### Setup and installation
[Install](https://opensearch.org/docs/latest/install-and-configure/install-opensearch/index/) and run an OpenSearch instance.
If you have Docker set up, we recommend pulling the Docker image and running it.
```shell
docker pull opensearchproject/opensearch:2.11.0
docker run -p 9200:9200 -p 9600:9600 -e "discovery.type=single-node" -e "ES_JAVA_OPTS=-Xms1024m -Xmx1024m" opensearchproject/opensearch:2.11.0
```
As an alternative, you can go to [OpenSearch integration GitHub](https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/opensearch) and start a Docker container running OpenSearch using the provided `docker-compose.yml`:
```shell
docker compose up
```
Once you have a running OpenSearch instance, install the `opensearch-haystack` integration:
```shell
pip install opensearch-haystack
```
## Usage
### On its own
This Retriever needs the `OpensearchDocumentStore` and indexed Documents to run. You cant use it on its own.
### In a RAG pipeline
Set your `OPENAI_API_KEY` as an environment variable and then run the following code:
```python
from haystack_integrations.components.retrievers.opensearch import (
OpenSearchBM25Retriever,
)
from haystack_integrations.document_stores.opensearch import OpenSearchDocumentStore
from haystack import Document
from haystack import Pipeline
from haystack.components.builders.answer_builder import AnswerBuilder
from haystack.components.builders.prompt_builder import PromptBuilder
from haystack.components.generators import OpenAIGenerator
from haystack.document_stores.types import DuplicatePolicy
import os
api_key = os.environ["OPENAI_API_KEY"]
## Create a RAG query pipeline
prompt_template = """
Given these documents, answer the question.\nDocuments:
{% for doc in documents %}
{{ doc.content }}
{% endfor %}
\nQuestion: {{question}}
\nAnswer:
"""
document_store = OpenSearchDocumentStore(
hosts="http://localhost:9200",
use_ssl=True,
verify_certs=False,
http_auth=("admin", "admin"),
)
## Add Documents
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
## DuplicatePolicy.SKIP param is optional, but useful to run the script multiple times without throwing errors
document_store.write_documents(documents=documents, policy=DuplicatePolicy.SKIP)
retriever = OpenSearchBM25Retriever(document_store=document_store)
rag_pipeline = Pipeline()
rag_pipeline.add_component(name="retriever", instance=retriever)
rag_pipeline.add_component(
instance=PromptBuilder(template=prompt_template),
name="prompt_builder",
)
rag_pipeline.add_component(instance=OpenAIGenerator(api_key=api_key), name="llm")
rag_pipeline.add_component(instance=AnswerBuilder(), name="answer_builder")
rag_pipeline.connect("retriever", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder", "llm")
rag_pipeline.connect("llm.replies", "answer_builder.replies")
rag_pipeline.connect("llm.metadata", "answer_builder.metadata")
rag_pipeline.connect("retriever", "answer_builder.documents")
question = "How many languages are spoken around the world today?"
result = rag_pipeline.run(
{
"retriever": {"query": question},
"prompt_builder": {"question": question},
"answer_builder": {"query": question},
},
)
print(result["answer_builder"]["answers"][0])
```
Heres an example output:
```python
GeneratedAnswer(
data='Over 7,000 languages are spoken around the world today.',
query='How many languages are spoken around the world today?',
documents=[
Document(id=cfe93bc1c274908801e6670440bf2bbba54fad792770d57421f85ffa2a4fcc94, content: 'There are over 7,000 languages spoken around the world today.', score: 7.179112),
Document(id=7f225626ad1019b273326fbaf11308edfca6d663308a4a3533ec7787367d59a2, content: 'In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the ph...', score: 1.1426818)],
meta={'model': 'gpt-5-mini', 'index': 0, 'finish_reason': 'stop', 'usage': {'prompt_tokens': 86, 'completion_tokens': 13, 'total_tokens': 99}})
```
## Additional References
🧑‍🍳 Cookbook: [PDF-Based Question Answering with Amazon Bedrock and Haystack](https://haystack.deepset.ai/cookbook/amazon_bedrock_for_documentation_qa)
@@ -0,0 +1,131 @@
---
title: "OpenSearchEmbeddingRetriever"
id: opensearchembeddingretriever
slug: "/opensearchembeddingretriever"
description: "An embedding-based Retriever compatible with the OpenSearch Document Store."
---
# OpenSearchEmbeddingRetriever
An embedding-based Retriever compatible with the OpenSearch Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of an [OpenSearchDocumentStore](../../document-stores/opensearch-document-store.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents |
| **API reference** | [OpenSearch](/reference/integrations-opensearch) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/opensearch |
</div>
## Overview
The `OpenSearchEmbeddingRetriever` is an embedding-based Retriever compatible with the `OpenSearchDocumentStore`. It compares the query and Document embeddings and fetches the Documents most relevant to the query from the `OpenSearchDocumentStore` based on the outcome.
When using the `OpenSearchEmbeddingRetriever` in your NLP system, make sure it has the query and Document embeddings available. You can do so by adding a Document Embedder to your indexing pipeline and a Text Embedder to your query pipeline.
In addition to the `query_embedding`, the `OpenSearchEmbeddingRetriever` accepts other optional parameters, including `top_k` (the maximum number of Documents to retrieve) and `filters` to narrow down the search space.
The `embedding_dim` for storing and retrieving embeddings must be defined when the corresponding `OpenSearchDocumentStore` is initialized.
### Setup and installation
[Install](https://opensearch.org/docs/latest/install-and-configure/install-opensearch/index/) and run an OpenSearch instance.
If you have Docker set up, we recommend pulling the Docker image and running it.
```shell
docker pull opensearchproject/opensearch:2.11.0
docker run -p 9200:9200 -p 9600:9600 -e "discovery.type=single-node" -e "ES_JAVA_OPTS=-Xms1024m -Xmx1024m" opensearchproject/opensearch:2.11.0
```
As an alternative, you can go to [OpenSearch integration GitHub](https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/opensearch) and start a Docker container running OpenSearch using the provided `docker-compose.yml`:
```shell
docker compose up
```
Once you have a running OpenSearch instance, install the `opensearch-haystack` integration:
```shell
pip install opensearch-haystack
```
## Usage
### In a pipeline
Use this Retriever in a query Pipeline like this:
```python
from haystack_integrations.components.retrievers.opensearch import (
OpenSearchEmbeddingRetriever,
)
from haystack_integrations.document_stores.opensearch import OpenSearchDocumentStore
from haystack.document_stores.types import DuplicatePolicy
from haystack import Document
from haystack import Pipeline
from haystack.components.embedders import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
document_store = OpenSearchDocumentStore(
hosts="http://localhost:9200",
use_ssl=True,
verify_certs=False,
http_auth=("admin", "admin"),
)
model = "sentence-transformers/all-mpnet-base-v2"
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
document_embedder = SentenceTransformersDocumentEmbedder(model=model)
documents_with_embeddings = document_embedder.run(documents)
document_store.write_documents(
documents_with_embeddings.get("documents"),
policy=DuplicatePolicy.SKIP,
)
query_pipeline = Pipeline()
query_pipeline.add_component(
"text_embedder",
SentenceTransformersTextEmbedder(model=model),
)
query_pipeline.add_component(
"retriever",
OpenSearchEmbeddingRetriever(document_store=document_store),
)
query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
query = "How many languages are there?"
result = query_pipeline.run({"text_embedder": {"text": query}})
print(result["retriever"]["documents"][0])
```
The example output would be:
```python
Document(id=cfe93bc1c274908801e6670440bf2bbba54fad792770d57421f85ffa2a4fcc94, content: 'There are over 7,000 languages spoken around the world today.', score: 0.70026743, embedding: vector of size 768)
```
## Additional References
🧑‍🍳 Cookbook: [PDF-Based Question Answering with Amazon Bedrock and Haystack](https://haystack.deepset.ai/cookbook/amazon_bedrock_for_documentation_qa)
@@ -0,0 +1,133 @@
---
title: "OpenSearchHybridRetriever"
id: opensearchhybridretriever
slug: "/opensearchhybridretriever"
description: "This is a [SuperComponent](../../concepts/components/supercomponents.mdx) that implements a Hybrid Retriever in a single component, relying on OpenSearch as the backend Document Store."
---
# OpenSearchHybridRetriever
This is a [SuperComponent](../../concepts/components/supercomponents.mdx) that implements a Hybrid Retriever in a single component, relying on OpenSearch as the backend Document Store.
A Hybrid Retriever uses both traditional keyword-based search (such as BM25) and embedding-based search to retrieve documents, combining the strengths of both approaches. The Retriever then merges and re-ranks the results from both methods.
<div className="key-value-table">
| | |
| --- | --- |
| Most common position in a pipeline | After an [OpenSearchDocumentStore](../../document-stores/opensearch-document-store.mdx) |
| Mandatory init variables | `document_store`: An instance of `OpenSearchDocumentStore` to use for retrieval <br /> <br />`embedder`: Any [Embedder](../embedders.mdx) implementing the `TextEmbedder` protocol |
| Mandatory run variables | `query`: A query string |
| Output variables | `documents`: A list of documents matching the query |
| API reference | [OpenSearch](/reference/integrations-opensearch) |
| GitHub | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/opensearch |
</div>
## Overview
The `OpenSearchHybridRetriever` combines two retrieval methods:
1. **BM25 Retrieval**: A keyword-based search that uses the BM25 algorithm to find documents based on term frequency and inverse document frequency. It's based on the [`OpenSearchBM25Retriever`](opensearchbm25retriever.mdx) component and is suitable for traditional keyword-based search.
2. **Embedding-based Retrieval**: A semantic search that uses vector similarity to find documents that are semantically similar to the query. It's based on the [`OpenSearchEmbeddingRetriever`](opensearchembeddingretriever.mdx) component and is suitable for semantic search.
The component automatically handles:
- Converting the query into an embedding using the provided embedded,
- Running both retrieval methods in parallel,
- Merging and re-ranking the results using the specified join mode.
### Setup and Installation
```shell
pip install opensearch-haystack
```
### Optional Parameters
This Retriever accepts various optional parameters. You can verify the most up-to-date list of parameters in our [API Reference](/reference/integrations-opensearch#opensearchhybridretriever).
You can pass additional parameters to the underlying components using the `bm25_retriever` and `embedding_retriever` dictionaries.
The `DocumentJoiner` parameters are all exposed on the `OpenSearchHybridRetriever` class, so you can set them directly.
Here's an example:
```python
retriever = OpenSearchHybridRetriever(
document_store=document_store,
embedder=embedder,
bm25_retriever={"raise_on_failure": True},
embedding_retriever={"raise_on_failure": False},
)
```
## Usage
### On its own
This Retriever needs the `OpensearchDocumentStore` populated with documents to run. You cant use it on its own.
### In a pipeline
Here's a basic example of how to use the `OpenSearchHybridRetriever`:
You can use the following command to run OpenSearch locally using Docker. Make sure you have Docker installed and running on your machine. Note that this example disables the security plugin for simplicity. In a production environment, you should enable security features.
```dockerfile
docker run -d \\
--name opensearch-nosec \\
-p 9200:9200 \\
-p 9600:9600 \\
-e "discovery.type=single-node" \\
-e "DISABLE_SECURITY_PLUGIN=true" \\
opensearchproject/opensearch:2.12.0
```
```python
from haystack import Document
from haystack.components.embedders import SentenceTransformersTextEmbedder, SentenceTransformersDocumentEmbedder
from haystack_integrations.components.retrievers.opensearch import OpenSearchHybridRetriever
from haystack_integrations.document_stores.opensearch import OpenSearchDocumentStore
## Initialize the document store
doc_store = OpenSearchDocumentStore(
hosts=["http://localhost:9200"],
index="document_store",
embedding_dim=384,
)
## Create some sample documents
docs = [
Document(content="Machine learning is a subset of artificial intelligence."),
Document(content="Deep learning is a subset of machine learning."),
Document(content="Natural language processing is a field of AI."),
Document(content="Reinforcement learning is a type of machine learning."),
Document(content="Supervised learning is a type of machine learning."),
]
## Embed the documents and add them to the document store
doc_embedder = SentenceTransformersDocumentEmbedder(model="sentence-transformers/all-MiniLM-L6-v2")
docs = doc_embedder.run(docs)
doc_store.write_documents(docs['documents'])
## Initialize some haystack text embedder, in this case the SentenceTransformersTextEmbedder
embedder = SentenceTransformersTextEmbedder(model="sentence-transformers/all-MiniLM-L6-v2")
## Initialize the hybrid retriever
retriever = OpenSearchHybridRetriever(
document_store=doc_store,
embedder=embedder,
top_k_bm25=3,
top_k_embedding=3,
join_mode="reciprocal_rank_fusion"
)
## Run the retriever
results = retriever.run(query="What is reinforcement learning?", filters_bm25=None, filters_embedding=None)
>> results['documents']
{'documents': [Document(id=..., content: 'Reinforcement learning is a type of machine learning.', score: 1.0),
Document(id=..., content: 'Supervised learning is a type of machine learning.', score: 0.9760624679979518),
Document(id=..., content: 'Deep learning is a subset of machine learning.', score: 0.4919354838709677),
Document(id=..., content: 'Machine learning is a subset of artificial intelligence.', score: 0.4841269841269841)]}
```
@@ -0,0 +1,128 @@
---
title: "PgvectorEmbeddingRetriever"
id: pgvectorembeddingretriever
slug: "/pgvectorembeddingretriever"
description: "An embedding-based Retriever compatible with the Pgvector Document Store."
---
# PgvectorEmbeddingRetriever
An embedding-based Retriever compatible with the Pgvector Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [PgvectorDocumentStore](../../document-stores/pgvectordocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A vector representing the query (a list of floats) |
| **Output variables** | `documents`: A list of documents |
| **API reference** | [Pgvector](/reference/integrations-pgvector) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/pgvector |
</div>
## Overview
The `PgvectorEmbeddingRetriever` is an embedding-based Retriever compatible with the `PgvectorDocumentStore`. It compares the query and Document embeddings and fetches the Documents most relevant to the query from the `PgvectorDocumentStore` based on the outcome.
When using the `PgvectorEmbeddingRetriever` in your Pipeline, make sure it has the query and Document embeddings available. You can do so by adding a Document Embedder to your indexing Pipeline and a Text Embedder to your query Pipeline.
In addition to the `query_embedding`, the `PgvectorEmbeddingRetriever` accepts other optional parameters, including `top_k` (the maximum number of Documents to retrieve) and `filters` to narrow down the search space.
Some relevant parameters that impact the embedding retrieval must be defined when the corresponding `PgvectorDocumentStore` is initialized: these include embedding dimension, vector function, and some others related to the search strategy (exact nearest neighbor or HNSW).
## Installation
To quickly set up a PostgreSQL database with pgvector, you can use Docker:
```shell
docker run -d -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=postgres ankane/pgvector
```
For more information on installing pgvector, visit the [pgvector GitHub repository](https://github.com/pgvector/pgvector).
To use pgvector with Haystack, install the `pgvector-haystack` integration:
```shell
pip install pgvector-haystack
```
## Usage
### On its own
This Retriever needs the `PgvectorDocumentStore` and indexed Documents to run.
```python
import os
from haystack_integrations.document_stores.pgvector import PgvectorDocumentStore
from haystack_integrations.components.retrievers.pgvector import (
PgvectorEmbeddingRetriever,
)
os.environ["PG_CONN_STR"] = "postgresql://postgres:postgres@localhost:5432/postgres"
document_store = PgvectorDocumentStore()
retriever = PgvectorEmbeddingRetriever(document_store=document_store)
## using a fake vector to keep the example simple
retriever.run(query_embedding=[0.1] * 768)
```
### In a Pipeline
```python
import os
from haystack.document_stores import DuplicatePolicy
from haystack import Document, Pipeline
from haystack.components.embedders import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
from haystack_integrations.document_stores.pgvector import PgvectorDocumentStore
from haystack_integrations.components.retrievers.pgvector import (
PgvectorEmbeddingRetriever,
)
os.environ["PG_CONN_STR"] = "postgresql://postgres:postgres@localhost:5432/postgres"
document_store = PgvectorDocumentStore(
embedding_dimension=768,
vector_function="cosine_similarity",
recreate_table=True,
)
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
document_embedder = SentenceTransformersDocumentEmbedder()
documents_with_embeddings = document_embedder.run(documents)
document_store.write_documents(
documents_with_embeddings.get("documents"),
policy=DuplicatePolicy.OVERWRITE,
)
query_pipeline = Pipeline()
query_pipeline.add_component("text_embedder", SentenceTransformersTextEmbedder())
query_pipeline.add_component(
"retriever",
PgvectorEmbeddingRetriever(document_store=document_store),
)
query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
query = "How many languages are there?"
result = query_pipeline.run({"text_embedder": {"text": query}})
print(result["retriever"]["documents"][0])
```
@@ -0,0 +1,146 @@
---
title: "PgvectorKeywordRetriever"
id: pgvectorkeywordretriever
slug: "/pgvectorkeywordretriever"
description: "This is a keyword-based Retriever that fetches documents matching a query from the Pgvector Document Store."
---
# PgvectorKeywordRetriever
This is a keyword-based Retriever that fetches documents matching a query from the Pgvector Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. Before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. Before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [PgvectorDocumentStore](../../document-stores/pgvectordocumentstore.mdx) |
| **Mandatory run variables** | `query`: A string |
| **Output variables** | `document`: A list of documents (matching the query) |
| **API reference** | [Pgvector](/reference/integrations-pgvector) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/pgvector |
</div>
## Overview
The `PgvectorKeywordRetriever` is a keyword-based Retriever compatible with the `PgvectorDocumentStore`.
The component uses the `ts_rank_cd` function of PostgreSQL to rank the documents.
It considers how often the query terms appear in the document, how close together the terms are in the document, and how important is the part of the document where they occur.
For more details, see [Postgres documentation](https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-RANKING).
Keep in mind that, unlike similar components such as `ElasticsearchBM25Retriever`, this Retriever does not apply fuzzy search out of the box, so its necessary to carefully formulate the query in order to avoid getting zero results.
In addition to the `query`, the `PgvectorKeywordRetriever` accepts other optional parameters, including `top_k` (the maximum number of documents to retrieve) and `filters` to narrow the search space.
### Installation
To quickly set up a PostgreSQL database with pgvector, you can use Docker:
```shell
docker run -d -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=postgres ankane/pgvector
```
For more information on how to install pgvector, visit the [pgvector GitHub repository](https://github.com/pgvector/pgvector).
Install the `pgvector-haystack` integration:
```shell
pip install pgvector-haystack
```
## Usage
### On its own
This Retriever needs the `PgvectorDocumentStore` and indexed documents to run.
Set an environment variable `PG_CONN_STR` with the connection string to your PostgreSQL database.
```python
from haystack_integrations.document_stores.pgvector import PgvectorDocumentStore
from haystack_integrations.components.retrievers.pgvector import (
PgvectorKeywordRetriever,
)
document_store = PgvectorDocumentStore()
retriever = PgvectorKeywordRetriever(document_store=document_store)
retriever.run(query="my nice query")
```
### In a RAG pipeline
The prerequisites necessary for running this code are:
- Set an environment variable `OPENAI_API_KEY` with your OpenAI API key.
- Set an environment variable `PG_CONN_STR` with the connection string to your PostgreSQL database.
```python
from haystack import Document
from haystack import Pipeline
from haystack.components.builders.answer_builder import AnswerBuilder
from haystack.components.builders.prompt_builder import PromptBuilder
from haystack.components.generators import OpenAIGenerator
from haystack.document_stores.types import DuplicatePolicy
from haystack_integrations.document_stores.pgvector import PgvectorDocumentStore
from haystack_integrations.components.retrievers.pgvector import (
PgvectorKeywordRetriever,
)
## Create a RAG query pipeline
prompt_template = """
Given these documents, answer the question.\nDocuments:
{% for doc in documents %}
{{ doc.content }}
{% endfor %}
\nQuestion: {{question}}
\nAnswer:
"""
document_store = PgvectorDocumentStore(
language="english", # this parameter influences text parsing for keyword retrieval
recreate_table=True,
)
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
## DuplicatePolicy.SKIP param is optional, but useful to run the script multiple times without throwing errors
document_store.write_documents(documents=documents, policy=DuplicatePolicy.SKIP)
retriever = PgvectorKeywordRetriever(document_store=document_store)
rag_pipeline = Pipeline()
rag_pipeline.add_component(name="retriever", instance=retriever)
rag_pipeline.add_component(
instance=PromptBuilder(template=prompt_template),
name="prompt_builder",
)
rag_pipeline.add_component(instance=OpenAIGenerator(), name="llm")
rag_pipeline.add_component(instance=AnswerBuilder(), name="answer_builder")
rag_pipeline.connect("retriever", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder", "llm")
rag_pipeline.connect("llm.replies", "answer_builder.replies")
rag_pipeline.connect("llm.meta", "answer_builder.meta")
rag_pipeline.connect("retriever", "answer_builder.documents")
question = "languages spoken around the world today"
result = rag_pipeline.run(
{
"retriever": {"query": question},
"prompt_builder": {"question": question},
"answer_builder": {"query": question},
},
)
print(result["answer_builder"])
```
@@ -0,0 +1,128 @@
---
title: "PineconeEmbeddingRetriever"
id: pineconedenseretriever
slug: "/pineconedenseretriever"
description: "An embedding-based Retriever compatible with the Pinecone Document Store."
---
# PineconeEmbeddingRetriever
An embedding-based Retriever compatible with the Pinecone Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [PineconeDocumentStore](../../document-stores/pinecone-document-store.mdx) |
| **Mandatory run variables** | `query_embedding`: A vector representing the query (a list of floats) |
| **Output variables** | `documents`: A list of documents |
| **API reference** | [Pinecone](/reference/integrations-pinecone) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/pinecone |
</div>
## Overview
The `PineconeEmbeddingRetriever` is an embedding-based Retriever compatible with the `PineconeDocumentStore`. It compares the query and Document embeddings and fetches the Documents most relevant to the query from the `PineconeDocumentStore` based on the outcome.
When using the `PineconeEmbeddingRetriever` in your NLP system, make sure it has the query and Document embeddings available. You can do so by adding a Document Embedder to your indexing Pipeline and a Text Embedder to your query Pipeline.
In addition to the `query_embedding`, the `PineconeEmbeddingRetriever` accepts other optional parameters, including `top_k` (the maximum number of Documents to retrieve) and `filters` to narrow down the search space.
Some relevant parameters that impact the embedding retrieval must be defined when the corresponding `PineconeDocumentStore` is initialized: these include the `dimension` of the embeddings and the distance `metric` to use.
## Usage
### On its own
This Retriever needs the `PineconeDocumentStore` and indexed Documents to run.
```python
from haystack_integrations.components.retrievers.pinecone import (
PineconeEmbeddingRetriever,
)
from haystack_integrations.document_stores.pinecone import PineconeDocumentStore
## Make sure you have the PINECONE_API_KEY environment variable set
document_store = PineconeDocumentStore(
index="my_index_with_documents",
namespace="my_namespace",
dimension=768,
)
retriever = PineconeEmbeddingRetriever(document_store=document_store)
## using an imaginary vector to keep the example simple, example run query:
retriever.run(query_embedding=[0.1] * 768)
```
### In a pipeline
Install the dependencies youll need:
```shell
pip install pinecone-haystack
pip install sentence-transformers
```
Use this Retriever in a query Pipeline like this:
```python
from haystack.document_stores.types import DuplicatePolicy
from haystack import Document
from haystack import Pipeline
from haystack.components.embedders import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
from haystack_integrations.components.retrievers.pinecone import (
PineconeEmbeddingRetriever,
)
from haystack_integrations.document_stores.pinecone import PineconeDocumentStore
## Make sure you have the PINECONE_API_KEY environment variable set
document_store = PineconeDocumentStore(
index="my_index",
namespace="my_namespace",
dimension=768,
)
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
document_embedder = SentenceTransformersDocumentEmbedder()
documents_with_embeddings = document_embedder.run(documents)
document_store.write_documents(
documents_with_embeddings.get("documents"),
policy=DuplicatePolicy.OVERWRITE,
)
query_pipeline = Pipeline()
query_pipeline.add_component("text_embedder", SentenceTransformersTextEmbedder())
query_pipeline.add_component(
"retriever",
PineconeEmbeddingRetriever(document_store=document_store),
)
query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
query = "How many languages are there?"
result = query_pipeline.run({"text_embedder": {"text": query}})
print(result["retriever"]["documents"][0])
```
The example output would be:
```python
Document(id=cfe93bc1c274908801e6670440bf2bbba54fad792770d57421f85ffa2a4fcc94, content: 'There are over 7,000 languages spoken around the world today.', score: 0.87717235, embedding: vector of size 768)
```
@@ -0,0 +1,117 @@
---
title: "QdrantEmbeddingRetriever"
id: qdrantembeddingretriever
slug: "/qdrantembeddingretriever"
description: "An embedding-based Retriever compatible with the Qdrant Document Store."
---
# QdrantEmbeddingRetriever
An embedding-based Retriever compatible with the Qdrant Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1\. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG Pipeline <br /> <br />2. The last component in the semantic search pipeline <br />3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [QdrantDocumentStore](../../document-stores/qdrant-document-store.mdx) |
| **Mandatory run variables** | `query_embedding`: A vector representing the query (a list of floats) |
| **Output variables** | `documents`: A list of documents |
| **API reference** | [Qdrant](/reference/integrations-qdrant) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/qdrant |
</div>
## Overview
The `QdrantEmbeddingRetriever` is an embedding-based Retriever compatible with the `QdrantDocumentStore`. It compares the query and Document embeddings and fetches the Documents most relevant to the query from the `QdrantDocumentStore` based on the outcome.
When using the `QdrantEmbeddingRetriever` in your NLP system, make sure it has the query and Document embeddings available. You can add a Document Embedder to your indexing Pipeline and a Text Embedder to your query Pipeline.
In addition to the `query_embedding`, the `QdrantEmbeddingRetriever` accepts other optional parameters, including `top_k` (the maximum number of Documents to retrieve) and `filters` to narrow down the search space.
Some relevant parameters that impact the embedding retrieval must be defined when the corresponding `QdrantDocumentStore` is initialized: these include the embedding dimension (`embedding_dim`), the `similarity` function to use when comparing embeddings and the HNWS configuration (`hnsw_config`).
### Installation
To start using Qdrant with Haystack, first install the package with:
```shell
pip install qdrant-haystack
```
### Usage
#### On its own
This Retriever needs the `QdrantDocumentStore` and indexed Documents to run.
```python
from haystack_integrations.components.retrievers.qdrant import QdrantEmbeddingRetriever
from haystack_integrations.document_stores.qdrant import QdrantDocumentStore
document_store = QdrantDocumentStore(
":memory:",
recreate_index=True,
return_embedding=True,
wait_result_from_api=True,
)
retriever = QdrantEmbeddingRetriever(document_store=document_store)
## using a fake vector to keep the example simple
retriever.run(query_embedding=[0.1] * 768)
```
#### In a Pipeline
```python
from haystack.document_stores.types import DuplicatePolicy
from haystack import Document
from haystack import Pipeline
from haystack.components.embedders import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
from haystack_integrations.components.retrievers.qdrant import QdrantEmbeddingRetriever
from haystack_integrations.document_stores.qdrant import QdrantDocumentStore
document_store = QdrantDocumentStore(
":memory:",
recreate_index=True,
return_embedding=True,
wait_result_from_api=True,
)
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
document_embedder = SentenceTransformersDocumentEmbedder()
documents_with_embeddings = document_embedder.run(documents)
document_store.write_documents(
documents_with_embeddings.get("documents"),
policy=DuplicatePolicy.OVERWRITE,
)
query_pipeline = Pipeline()
query_pipeline.add_component("text_embedder", SentenceTransformersTextEmbedder())
query_pipeline.add_component(
"retriever",
QdrantEmbeddingRetriever(document_store=document_store),
)
query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
query = "How many languages are there?"
result = query_pipeline.run({"text_embedder": {"text": query}})
print(result["retriever"]["documents"][0])
```
@@ -0,0 +1,190 @@
---
title: "QdrantHybridRetriever"
id: qdranthybridretriever
slug: "/qdranthybridretriever"
description: "A Retriever based both on dense and sparse embeddings, compatible with the Qdrant Document Store."
---
# QdrantHybridRetriever
A Retriever based both on dense and sparse embeddings, compatible with the Qdrant Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1\. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline <br /> <br />2. The last component in a hybrid search pipeline <br /> 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [QdrantDocumentStore](../../document-stores/qdrant-document-store.mdx) |
| **Mandatory run variables** | `query_embedding`: A dense vector representing the query (a list of floats) <br /> <br />`query_sparse_embedding`: A [`SparseEmbedding`](../../concepts/data-classes.mdx#sparseembedding) object containing a vectorial representation of the query |
| **Output variables** | `document`: A list of documents |
| **API reference** | [Qdrant](/reference/integrations-qdrant) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/qdrant |
</div>
## Overview
The `QdrantHybridRetriever` is a Retriever based both on dense and sparse embeddings, compatible with the [`QdrantDocumentStore`](../../document-stores/qdrant-document-store.mdx).
It compares the query and documents dense and sparse embeddings and fetches the documents most relevant to the query from the `QdrantDocumentStore`, fusing the scores with Reciprocal Rank Fusion.
:::tip[Hybrid Retrieval Pipeline]
If you want additional customization for merging or fusing results, consider creating a hybrid retrieval pipeline with [`DocumentJoiner`](../joiners/documentjoiner.mdx).
You can check out our hybrid retrieval pipeline [tutorial](https://haystack.deepset.ai/tutorials/33_hybrid_retrieval) for detailed steps.
:::
When using the `QdrantHybridRetriever`, make sure it has the query and document with dense and sparse embeddings available. You can do so by:
- Adding a (dense) document Embedder and a sparse document Embedder to your indexing pipeline,
- Adding a (dense) text Embedder and a sparse text Embedder to your query pipeline.
In addition to `query_embedding` and `query_sparse_embedding`, the `QdrantHybridRetriever` accepts other optional parameters, including `top_k` (the maximum number of documents to retrieve) and `filters` to narrow down the search space.
:::note[Sparse Embedding Support]
To use Sparse Embedding support, you need to initialize the `QdrantDocumentStore` with `use_sparse_embeddings=True`, which is `False` by default.
If you want to use Document Store or collection previously created with this feature disabled, you must migrate the existing data. You can do this by taking advantage of the `migrate_to_sparse_embeddings_support` utility function.
:::
### Installation
To start using Qdrant with Haystack, first install the package with:
```shell
pip install qdrant-haystack
```
## Usage
### On its own
```python
from haystack_integrations.components.retrievers.qdrant import QdrantHybridRetriever
from haystack_integrations.document_stores.qdrant import QdrantDocumentStore
from haystack.dataclasses import Document, SparseEmbedding
document_store = QdrantDocumentStore(
":memory:",
use_sparse_embeddings=True,
recreate_index=True,
return_embedding=True,
wait_result_from_api=True,
)
doc = Document(
content="test",
embedding=[0.5] * 768,
sparse_embedding=SparseEmbedding(indices=[0, 3, 5], values=[0.1, 0.5, 0.12]),
)
document_store.write_documents([doc])
retriever = QdrantHybridRetriever(document_store=document_store)
embedding = [0.1] * 768
sparse_embedding = SparseEmbedding(indices=[0, 1, 2, 3], values=[0.1, 0.8, 0.05, 0.33])
retriever.run(query_embedding=embedding, query_sparse_embedding=sparse_embedding)
```
### In a pipeline
Currently, you can compute sparse embeddings using Fastembed Sparse Embedders.
First, install the package with:
```shell
pip install fastembed-haystack
```
In the example below, we are using Fastembed Embedders to compute dense embeddings as well.
```python
from haystack import Document, Pipeline
from haystack.components.writers import DocumentWriter
from haystack_integrations.components.retrievers.qdrant import QdrantHybridRetriever
from haystack_integrations.document_stores.qdrant import QdrantDocumentStore
from haystack.document_stores.types import DuplicatePolicy
from haystack_integrations.components.embedders.fastembed import (
FastembedTextEmbedder,
FastembedDocumentEmbedder,
FastembedSparseTextEmbedder,
FastembedSparseDocumentEmbedder,
)
document_store = QdrantDocumentStore(
":memory:",
recreate_index=True,
use_sparse_embeddings=True,
embedding_dim=384,
)
documents = [
Document(content="My name is Wolfgang and I live in Berlin"),
Document(content="I saw a black horse running"),
Document(content="Germany has many big cities"),
Document(content="fastembed is supported by and maintained by Qdrant."),
]
indexing = Pipeline()
indexing.add_component(
"sparse_doc_embedder",
FastembedSparseDocumentEmbedder(model="prithvida/Splade_PP_en_v1"),
)
indexing.add_component(
"dense_doc_embedder",
FastembedDocumentEmbedder(model="BAAI/bge-small-en-v1.5"),
)
indexing.add_component(
"writer",
DocumentWriter(document_store=document_store, policy=DuplicatePolicy.OVERWRITE),
)
indexing.connect("sparse_doc_embedder", "dense_doc_embedder")
indexing.connect("dense_doc_embedder", "writer")
indexing.run({"sparse_doc_embedder": {"documents": documents}})
querying = Pipeline()
querying.add_component(
"sparse_text_embedder",
FastembedSparseTextEmbedder(model="prithvida/Splade_PP_en_v1"),
)
querying.add_component(
"dense_text_embedder",
FastembedTextEmbedder(
model="BAAI/bge-small-en-v1.5",
prefix="Represent this sentence for searching relevant passages: ",
),
)
querying.add_component(
"retriever",
QdrantHybridRetriever(document_store=document_store),
)
querying.connect(
"sparse_text_embedder.sparse_embedding",
"retriever.query_sparse_embedding",
)
querying.connect("dense_text_embedder.embedding", "retriever.query_embedding")
question = "Who supports fastembed?"
results = query_mix.run(
{
"dense_text_embedder": {"text": question},
"sparse_text_embedder": {"text": question},
},
)
print(result["retriever"]["documents"][0])
## Document(id=...,
## content: 'fastembed is supported by and maintained by Qdrant.',
## score: 1.0)
```
## Additional References
:notebook: Tutorial: [Creating a Hybrid Retrieval Pipeline](https://haystack.deepset.ai/tutorials/33_hybrid_retrieval)
🧑‍🍳 Cookbook: [Sparse Embedding Retrieval with Qdrant and FastEmbed](https://haystack.deepset.ai/cookbook/sparse_embedding_retrieval)
@@ -0,0 +1,153 @@
---
title: "QdrantSparseEmbeddingRetriever"
id: qdrantsparseembeddingretriever
slug: "/qdrantsparseembeddingretriever"
description: "A Retriever based on sparse embeddings, compatible with the Qdrant Document Store."
---
# QdrantSparseEmbeddingRetriever
A Retriever based on sparse embeddings, compatible with the Qdrant Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1\. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline <br /> <br />2. The last component in the semantic search pipeline <br /> 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [QdrantDocumentStore](../../document-stores/qdrant-document-store.mdx) |
| **Mandatory run variables** | `query_sparse_embedding`: A [`SparseEmbedding`](../../concepts/data-classes.mdx#sparseembedding) object containing a vectorial representation of the query |
| **Output variables** | `documents`: A list of documents |
| **API reference** | [Qdrant](/reference/integrations-qdrant) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/qdrant |
</div>
## Overview
The `QdrantSparseEmbeddingRetriever` is a Retriever based on sparse embeddings, compatible with the [`QdrantDocumentStore`](../../document-stores/qdrant-document-store.mdx).
It compares the query and document sparse embeddings and, based on the outcome, fetches the documents most relevant to the query from the `QdrantDocumentStore`.
When using the `QdrantSparseEmbeddingRetriever`, make sure it has the query and document sparse embeddings available. You can do so by adding a sparse document Embedder to your indexing pipeline and a sparse text Embedder to your query pipeline.
In addition to the `query_sparse_embedding`, the `QdrantSparseEmbeddingRetriever` accepts other optional parameters, including `top_k` (the maximum number of documents to retrieve) and `filters` to narrow down the search space.
:::note[Sparse Embedding Support]
To use Sparse Embedding support, you need to initialize the `QdrantDocumentStore` with `use_sparse_embeddings=True`, which is `False` by default.
If you want to use Document Store or collection previously created with this feature disabled, you must migrate the existing data. You can do this by taking advantage of the `migrate_to_sparse_embeddings_support` utility function.
:::
### Installation
To start using Qdrant with Haystack, first install the package with:
```shell
pip install qdrant-haystack
```
## Usage
### On its own
This Retriever needs the `QdrantDocumentStore` and indexed documents to run.
```python
from haystack_integrations.components.retrievers.qdrant import (
QdrantSparseEmbeddingRetriever,
)
from haystack_integrations.document_stores.qdrant import QdrantDocumentStore
from haystack.dataclasses import Document, SparseEmbedding
document_store = QdrantDocumentStore(
":memory:",
use_sparse_embeddings=True,
recreate_index=True,
return_embedding=True,
)
doc = Document(
content="test",
sparse_embedding=SparseEmbedding(indices=[0, 3, 5], values=[0.1, 0.5, 0.12]),
)
document_store.write_documents([doc])
retriever = QdrantSparseEmbeddingRetriever(document_store=document_store)
sparse_embedding = SparseEmbedding(indices=[0, 1, 2, 3], values=[0.1, 0.8, 0.05, 0.33])
retriever.run(query_sparse_embedding=sparse_embedding)
```
### In a pipeline
In Haystack, you can compute sparse embeddings using Fastembed Embedders.
First, install the package with:
```shell
pip install fastembed-haystack
```
Then, try out this pipeline:
```python
from haystack import Document, Pipeline
from haystack.components.writers import DocumentWriter
from haystack_integrations.components.retrievers.qdrant import (
QdrantSparseEmbeddingRetriever,
)
from haystack_integrations.document_stores.qdrant import QdrantDocumentStore
from haystack.document_stores.types import DuplicatePolicy
from haystack_integrations.components.embedders.fastembed import (
FastembedDocumentEmbedder,
FastembedTextEmbedder,
)
document_store = QdrantDocumentStore(
":memory:",
recreate_index=True,
use_sparse_embeddings=True,
)
documents = [
Document(content="My name is Wolfgang and I live in Berlin"),
Document(content="I saw a black horse running"),
Document(content="Germany has many big cities"),
Document(content="fastembed is supported by and maintained by Qdrant."),
]
sparse_document_embedder = FastembedSparseDocumentEmbedder()
writer = DocumentWriter(document_store=document_store, policy=DuplicatePolicy.OVERWRITE)
indexing_pipeline = Pipeline()
indexing_pipeline.add_component("sparse_document_embedder", sparse_document_embedder)
indexing_pipeline.add_component("writer", writer)
indexing_pipeline.connect("sparse_document_embedder", "writer")
indexing_pipeline.run({"sparse_document_embedder": {"documents": documents}})
query_pipeline = Pipeline()
query_pipeline.add_component("sparse_text_embedder", FastembedSparseTextEmbedder())
query_pipeline.add_component(
"sparse_retriever",
QdrantSparseEmbeddingRetriever(document_store=document_store),
)
query_pipeline.connect(
"sparse_text_embedder.sparse_embedding",
"sparse_retriever.query_sparse_embedding",
)
query = "Who supports fastembed?"
result = query_pipeline.run({"sparse_text_embedder": {"text": query}})
print(result["sparse_retriever"]["documents"][0]) # noqa: T201
## Document(id=...,
## content: 'fastembed is supported by and maintained by Qdrant.',
## score: 0.758..)
```
## Additional References
🧑‍🍳 Cookbook: [Sparse Embedding Retrieval with Qdrant and FastEmbed](https://haystack.deepset.ai/cookbook/sparse_embedding_retrieval)
@@ -0,0 +1,86 @@
---
title: "SentenceWindowRetriever"
id: sentencewindowretrieval
slug: "/sentencewindowretrieval"
description: "Use this component to retrieve neighboring sentences around relevant sentences to get the full context."
---
# SentenceWindowRetriever
Use this component to retrieve neighboring sentences around relevant sentences to get the full context.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | Used after the main Retriever component, like the `InMemoryEmbeddingRetriever` or any other Retriever. |
| **Mandatory init variables** | `document_store`: An instance of a Document Store |
| **Mandatory run variables** | `retrieved_documents`: A list of already retrieved documents for which you want to get a context window |
| **Output variables** | `context_windows`: A list of strings <br /> <br />`context_documents`: A list of documents ordered by `split_idx_start` |
| **API reference** | [Retrievers](/reference/retrievers-api) |
| **GitHub link** | https://github.com/deepset-ai/haystack/blob/main/haystack/components/retrievers/sentence_window_retriever.py |
</div>
## Overview
The "sentence window" is a retrieval technique that allows for the retrieval of the context around relevant sentences.
During indexing, documents are broken into smaller chunks or sentences and indexed. During retrieval, the sentences most relevant to a given query, based on a certain similarity metric, are retrieved.
Once we have the relevant sentences, we can retrieve neighboring sentences to provide full context. The number of neighboring sentences to retrieve is defined by a fixed number of sentences before and after the relevant sentence.
This component is meant to be used with other Retrievers, such as the `InMemoryEmbeddingRetriever`. These Retrievers find relevant sentences by comparing a query against indexed sentences using a similarity metric. Then, the `SentenceWindowRetriever` component retrieves neighboring sentences around the relevant ones by leveraging metadata stored in the `Document` object.
## Usage
### On its own
```python
splitter = DocumentSplitter(split_length=10, split_overlap=5, split_by="word")
text = (
"This is a text with some words. There is a second sentence. And there is also a third sentence. "
"It also contains a fourth sentence. And a fifth sentence. And a sixth sentence. And a seventh sentence"
)
doc = Document(content=text)
docs = splitter.run([doc])
doc_store = InMemoryDocumentStore()
doc_store.write_documents(docs["documents"])
retriever = SentenceWindowRetriever(document_store=doc_store, window_size=3)
```
### In a Pipeline
```python
from haystack import Document, Pipeline
from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
from haystack.components.retrievers import SentenceWindowRetriever
from haystack.components.preprocessors import DocumentSplitter
from haystack.document_stores.in_memory import InMemoryDocumentStore
splitter = DocumentSplitter(split_length=10, split_overlap=5, split_by="word")
text = (
"This is a text with some words. There is a second sentence. And there is also a third sentence. "
"It also contains a fourth sentence. And a fifth sentence. And a sixth sentence. And a seventh sentence"
)
doc = Document(content=text)
docs = splitter.run([doc])
doc_store = InMemoryDocumentStore()
doc_store.write_documents(docs["documents"])
rag = Pipeline()
rag.add_component("bm25_retriever", InMemoryBM25Retriever(doc_store, top_k=1))
rag.add_component(
"sentence_window_retriever",
SentenceWindowRetriever(document_store=doc_store, window_size=3),
)
rag.connect("bm25_retriever", "sentence_window_retriever")
rag.run({"bm25_retriever": {"query": "third"}})
```
## Additional References
:notebook: Tutorial: [Retrieving a Context Window Around a Sentence](https://haystack.deepset.ai/tutorials/42_sentence_window_retriever)
@@ -0,0 +1,84 @@
---
title: "SnowflakeTableRetriever"
id: snowflaketableretriever
slug: "/snowflaketableretriever"
description: "Connects to a Snowflake database to execute an SQL query."
---
# SnowflakeTableRetriever
Connects to a Snowflake database to execute an SQL query.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | Before a [`PromptBuilder`](../builders/promptbuilder.mdx) |
| **Mandatory init variables** | `user`: User's login <br /> <br />`account`: Snowflake account identifier <br /> <br />`api_key`: Snowflake account password. Can be set with `SNOWFLAKE_API_KEY` env var |
| **Mandatory run variables** | `query`: An SQL query to execute |
| **Output variables** | `dataframe`: The resulting Pandas dataframe version of the table |
| **API reference** | [Snowflake](/reference/integrations-snowflake) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/snowflake |
</div>
## Overview
The `SnowflakeTableRetriever` connects to a Snowflake database and retrieves data using an SQL query. It then returns a Pandas dataframe and a Markdown version of the table:
To start using the integration, install it with:
```bash
pip install snowflake-haystack
```
## Usage
### On its own
```python
from haystack_integrations.components.retrievers.snowflake import SnowflakeTableRetriever
snowflake = SnowflakeRetriever(
user="<ACCOUNT-USER>",
account="<ACCOUNT-IDENTIFIER>",
api_key=Secret.from_env_var("SNOWFLAKE_API_KEY"),
warehouse="<WAREHOUSE-NAME>",
)
snowflake.run(query="""select * from table limit 10;"""")
```
### In a pipeline
In the following pipeline example, the `PromptBuilder` is using the table received from the `SnowflakeTableRetriever` to create a prompt template and pass it on to an LLM:
```python
from haystack import Pipeline
from haystack.utils import Secret
from haystack.components.builders import PromptBuilder
from haystack.components.generators import OpenAIGenerator
from haystack_integrations.components.retrievers.snowflake import (
SnowflakeTableRetriever,
)
executor = SnowflakeTableRetriever(
user="<ACCOUNT-USER>",
account="<ACCOUNT-IDENTIFIER>",
api_key=Secret.from_env_var("SNOWFLAKE_API_KEY"),
warehouse="<WAREHOUSE-NAME>",
)
pipeline = Pipeline()
pipeline.add_component(
"builder",
PromptBuilder(template="Describe this table: {{ table }}"),
)
pipeline.add_component("snowflake", executor)
pipeline.add_component("llm", OpenAIGenerator(model="gpt-4o"))
pipeline.connect("snowflake.table", "builder.table")
pipeline.connect("builder", "llm")
pipeline.run(data={"query": "select employee, salary from table limit 10;"})
```
@@ -0,0 +1,115 @@
---
title: "ValkeyEmbeddingRetriever"
id: valkeyembeddingretriever
slug: "/valkeyembeddingretriever"
description: "This is an embedding Retriever compatible with the Valkey Document Store."
---
# ValkeyEmbeddingRetriever
This is an embedding Retriever compatible with the Valkey Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`ChatPromptBuilder`](../builders/chatpromptbuilder.mdx) or [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in a semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [ValkeyDocumentStore](../../document-stores/valkeydocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents |
| **API reference** | [Valkey](/reference/integrations-valkey) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/valkey |
</div>
## Overview
The `ValkeyEmbeddingRetriever` is an embedding-based Retriever compatible with the [`ValkeyDocumentStore`](../../document-stores/valkeydocumentstore.mdx). It compares the query and Document embeddings and fetches the Documents most relevant to the query from the `ValkeyDocumentStore` based on vector similarity.
### Parameters
When using the `ValkeyEmbeddingRetriever` in your system, ensure the query and Document [embeddings](../embedders.mdx) are available. You can do so by adding a Document embedder to your indexing pipeline and a text embedder to your query pipeline.
In addition to the `query_embedding`, the `ValkeyEmbeddingRetriever` accepts other optional parameters, including `top_k` (the maximum number of Documents to retrieve) and `filters` to narrow down the search space.
## Usage
### Installation
To start using Valkey with Haystack, install the package with:
```shell
pip install valkey-haystack
```
### On its own
This Retriever needs an instance of `ValkeyDocumentStore` and indexed Documents to run.
```python
from haystack_integrations.document_stores.valkey import ValkeyDocumentStore
from haystack_integrations.components.retrievers.valkey import ValkeyEmbeddingRetriever
document_store = ValkeyDocumentStore(
nodes_list=[("localhost", 6379)],
index_name="my_documents",
embedding_dim=768,
distance_metric="cosine",
)
retriever = ValkeyEmbeddingRetriever(document_store=document_store)
# Using a fake vector to keep the example simple
retriever.run(query_embedding=[0.1] * 768)
```
### In a Pipeline
```python
from haystack import Document, Pipeline
from haystack.components.embedders import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
from haystack.components.writers import DocumentWriter
from haystack_integrations.document_stores.valkey import ValkeyDocumentStore
from haystack_integrations.components.retrievers.valkey import ValkeyEmbeddingRetriever
document_store = ValkeyDocumentStore(
nodes_list=[("localhost", 6379)],
index_name="my_documents",
embedding_dim=768,
distance_metric="cosine",
)
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
indexing = Pipeline()
indexing.add_component("embedder", SentenceTransformersDocumentEmbedder())
indexing.add_component("writer", DocumentWriter(document_store))
indexing.connect("embedder.documents", "writer.documents")
indexing.run({"embedder": {"documents": documents}})
query_pipeline = Pipeline()
query_pipeline.add_component("text_embedder", SentenceTransformersTextEmbedder())
query_pipeline.add_component(
"retriever",
ValkeyEmbeddingRetriever(document_store=document_store),
)
query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
query = "How many languages are there?"
result = query_pipeline.run({"text_embedder": {"text": query}})
print(result["retriever"]["documents"][0])
```
For a full RAG example with `ValkeyEmbeddingRetriever`, see the [ValkeyDocumentStore](../../document-stores/valkeydocumentstore.mdx#using-valkey-in-a-rag-pipeline) documentation.
@@ -0,0 +1,135 @@
---
title: "WeaviateBM25Retriever"
id: weaviatebm25retriever
slug: "/weaviatebm25retriever"
description: "This is a keyword-based Retriever that fetches Documents matching a query from the Weaviate Document Store."
---
# WeaviateBM25Retriever
This is a keyword-based Retriever that fetches Documents matching a query from the Weaviate Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. Before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. Before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [WeaviateDocumentStore](../../document-stores/weaviatedocumentstore.mdx) |
| **Mandatory run variables** | `query`: A string |
| **Output variables** | `documents`: A list of documents (matching the query) |
| **API reference** | [Weaviate](/reference/integrations-weaviate) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/weaviate |
</div>
## Overview
`WeaviateBM25Retriever` is a keyword-based Retriever that fetches Documents matching a query from [`WeaviateDocumentStore`](../../document-stores/weaviatedocumentstore.mdx). It determines the similarity between Documents and the query based on the BM25 algorithm, which computes a weighted word overlap between the
two strings.
Since the `WeaviateBM25Retriever` matches strings based on word overlap, its often used to find exact matches to names of persons or products, IDs, or well-defined error messages. The BM25 algorithm is very lightweight and simple. Beating it with more complex embedding-based approaches on out-of-domain data can be hard.
If you want a semantic match between a query and documents, use the [`WeaviateEmbeddingRetriever`](weaviateembeddingretriever.mdx), which uses vectors created by embedding models to retrieve relevant information.
### Parameters
In addition to the `query`, the `WeaviateBM25Retriever` accepts other optional parameters, including `top_k` (the maximum number of Documents to retrieve) and `filters` to narrow down the search space.
### Usage
### Installation
To start using Weaviate with Haystack, install the package with:
```shell
pip install weaviate-haystack
```
#### On its own
This Retriever needs an instance of `WeaviateDocumentStore` and indexed Documents to run.
```python
from haystack_integrations.document_stores.weaviate.document_store import (
WeaviateDocumentStore,
)
from haystack_integrations.components.retrievers.weaviate import WeaviateBM25Retriever
document_store = WeaviateDocumentStore(url="http://localhost:8080")
retriever = WeaviateBM25Retriever(document_store=document_store)
retriever.run(query="How to make a pizza", top_k=3)
```
#### In a Pipeline
```python
from haystack_integrations.document_stores.weaviate.document_store import (
WeaviateDocumentStore,
)
from haystack_integrations.components.retrievers.weaviate import (
WeaviateBM25Retriever,
)
from haystack import Document
from haystack import Pipeline
from haystack.components.builders.answer_builder import AnswerBuilder
from haystack.components.builders.prompt_builder import PromptBuilder
from haystack.components.generators import OpenAIGenerator
from haystack.document_stores.types import DuplicatePolicy
## Create a RAG query pipeline
prompt_template = """
Given these documents, answer the question.\nDocuments:
{% for doc in documents %}
{{ doc.content }}
{% endfor %}
\nQuestion: {{question}}
\nAnswer:
"""
document_store = WeaviateDocumentStore(url="http://localhost:8080")
## Add Documents
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
## DuplicatePolicy.SKIP param is optional, but useful to run the script multiple times without throwing errors
document_store.write_documents(documents=documents, policy=DuplicatePolicy.SKIP)
rag_pipeline = Pipeline()
rag_pipeline.add_component(
name="retriever",
instance=WeaviateBM25Retriever(document_store=document_store),
)
rag_pipeline.add_component(
instance=PromptBuilder(template=prompt_template),
name="prompt_builder",
)
rag_pipeline.add_component(instance=OpenAIGenerator(), name="llm")
rag_pipeline.add_component(instance=AnswerBuilder(), name="answer_builder")
rag_pipeline.connect("retriever", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder", "llm")
rag_pipeline.connect("llm.replies", "answer_builder.replies")
rag_pipeline.connect("llm.metadata", "answer_builder.metadata")
rag_pipeline.connect("retriever", "answer_builder.documents")
question = "How many languages are spoken around the world today?"
result = rag_pipeline.run(
{
"retriever": {"query": question},
"prompt_builder": {"question": question},
"answer_builder": {"query": question},
},
)
print(result["answer_builder"]["answers"][0])
```
@@ -0,0 +1,120 @@
---
title: "WeaviateEmbeddingRetriever"
id: weaviateembeddingretriever
slug: "/weaviateembeddingretriever"
description: "This is an embedding Retriever compatible with the Weaviate Document Store."
---
# WeaviateEmbeddingRetriever
This is an embedding Retriever compatible with the Weaviate Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [WeaviateDocumentStore](../../document-stores/weaviatedocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents |
| **API reference** | [Weaviate](/reference/integrations-weaviate) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/weaviate |
</div>
## Overview
The `WeaviateEmbeddingRetriever` is an embedding-based Retriever compatible with the [`WeaviateDocumentStore`](../../document-stores/weaviatedocumentstore.mdx). It compares the query and Document embeddings and fetches the Documents most relevant to the query from the `WeaviateDocumentStore` based on the outcome.
### Parameters
When using the `WeaviateEmbeddingRetriever` in your NLP system, ensure the query and Document [embeddings](../embedders.mdx) are available. You can do so by adding a Document Embedder to your indexing Pipeline and a Text Embedder to your query Pipeline.
In addition to the `query_embedding`, the `WeaviateEmbeddingRetriever` accepts other optional parameters, including `top_k` (the maximum number of Documents to retrieve) and `filters` to narrow down the search space.
You can also specify `distance`, the maximum allowed distance between embeddings, and `certainty`, the normalized distance between the result items and the search embedding. The behavior of `distance` depends on the Collections distance metric used. See the [official Weaviate documentation](https://weaviate.io/developers/weaviate/api/graphql/search-operators#variables) for more information.
The embedding similarity function depends on the vectorizer used in the `WeaviateDocumentStore` collection. Check out the [official Weaviate documentation](https://weaviate.io/developers/weaviate/modules/retriever-vectorizer-modules) to see all the supported vectorizers.
## Usage
### Installation
To start using Weaviate with Haystack, install the package with:
```shell
pip install weaviate-haystack
```
### On its own
This Retriever needs an instance of `WeaviateDocumentStore` and indexed Documents to run.
```python
from haystack_integrations.document_stores.weaviate.document_store import (
WeaviateDocumentStore,
)
from haystack_integrations.components.retrievers.weaviate import (
WeaviateEmbeddingRetriever,
)
document_store = WeaviateDocumentStore(url="http://localhost:8080")
retriever = WeaviateEmbeddingRetriever(document_store=document_store)
## using a fake vector to keep the example simple
retriever.run(query_embedding=[0.1] * 768)
```
### In a Pipeline
```python
from haystack.document_stores.types import DuplicatePolicy
from haystack import Document
from haystack import Pipeline
from haystack.components.embedders import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
from haystack_integrations.document_stores.weaviate.document_store import (
WeaviateDocumentStore,
)
from haystack_integrations.components.retrievers.weaviate import (
WeaviateEmbeddingRetriever,
)
document_store = WeaviateDocumentStore(url="http://localhost:8080")
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
document_embedder = SentenceTransformersDocumentEmbedder()
documents_with_embeddings = document_embedder.run(documents)
document_store.write_documents(
documents_with_embeddings.get("documents"),
policy=DuplicatePolicy.OVERWRITE,
)
query_pipeline = Pipeline()
query_pipeline.add_component("text_embedder", SentenceTransformersTextEmbedder())
query_pipeline.add_component(
"retriever",
WeaviateEmbeddingRetriever(document_store=document_store),
)
query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
query = "How many languages are there?"
result = query_pipeline.run({"text_embedder": {"text": query}})
print(result["retriever"]["documents"][0])
```
@@ -0,0 +1,158 @@
---
title: "WeaviateHybridRetriever"
id: weaviatehybridretriever
slug: "/weaviatehybridretriever"
description: "A Retriever that combines BM25 keyword search and vector similarity to fetch documents from the Weaviate Document Store."
---
# WeaviateHybridRetriever
A Retriever that combines BM25 keyword search and vector similarity to fetch documents from the Weaviate Document Store.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in a hybrid search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [WeaviateDocumentStore](../../document-stores/weaviatedocumentstore.mdx) |
| **Mandatory run variables** | `query`: A string <br /> <br />`query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents (matching the query) |
| **API reference** | [Weaviate](/reference/integrations-weaviate) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/weaviate |
</div>
## Overview
The `WeaviateHybridRetriever` combines keyword-based (BM25) and vector similarity search to fetch documents from the [`WeaviateDocumentStore`](../../document-stores/weaviatedocumentstore.mdx). Weaviate executes both searches in parallel and fuses the results into a single ranked list. The Retriever requires both a text query and its corresponding embedding.
The `alpha` parameter controls how much each search method contributes to the final results:
- `alpha = 0.0`: only keyword (BM25) scoring is used,
- `alpha = 1.0`: only vector similarity scoring is used,
- Values in between blend the two; higher values favor the vector score, lower values favor BM25.
If you don't specify `alpha`, the Weaviate server default is used.
You can also use the `max_vector_distance` parameter to set a threshold for the vector component. Candidates with a distance larger than this threshold are excluded from the vector portion before blending.
See the [official Weaviate documentation](https://weaviate.io/developers/weaviate/search/hybrid#parameters) for more details on hybrid search parameters.
### Parameters
When using the `WeaviateHybridRetriever`, you need to provide both the query text and its embedding. You can do this by adding a Text Embedder to your query pipeline.
In addition to `query` and `query_embedding`, the retriever accepts optional parameters including `top_k` (the maximum number of documents to return), `filters` to narrow down the search space, and `filter_policy` to determine how filters are applied.
## Usage
### Installation
To start using Weaviate with Haystack, install the package with:
```shell
pip install weaviate-haystack
```
### On its own
This Retriever needs an instance of `WeaviateDocumentStore` and indexed documents to run.
```python
from haystack_integrations.document_stores.weaviate.document_store import (
WeaviateDocumentStore,
)
from haystack_integrations.components.retrievers.weaviate import WeaviateHybridRetriever
document_store = WeaviateDocumentStore(url="http://localhost:8080")
retriever = WeaviateHybridRetriever(document_store=document_store)
## using a fake vector to keep the example simple
retriever.run(query="How many languages are there?", query_embedding=[0.1] * 768)
```
### In a pipeline
```python
from haystack.document_stores.types import DuplicatePolicy
from haystack import Document
from haystack import Pipeline
from haystack.components.embedders import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
from haystack_integrations.document_stores.weaviate.document_store import (
WeaviateDocumentStore,
)
from haystack_integrations.components.retrievers.weaviate import (
WeaviateHybridRetriever,
)
document_store = WeaviateDocumentStore(url="http://localhost:8080")
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
document_embedder = SentenceTransformersDocumentEmbedder()
documents_with_embeddings = document_embedder.run(documents)
document_store.write_documents(
documents_with_embeddings.get("documents"),
policy=DuplicatePolicy.OVERWRITE,
)
query_pipeline = Pipeline()
query_pipeline.add_component("text_embedder", SentenceTransformersTextEmbedder())
query_pipeline.add_component(
"retriever",
WeaviateHybridRetriever(document_store=document_store),
)
query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
query = "How many languages are there?"
result = query_pipeline.run(
{"text_embedder": {"text": query}, "retriever": {"query": query}},
)
print(result["retriever"]["documents"][0])
```
### Adjusting the Alpha Parameter
You can set the `alpha` parameter at initialization or override it at query time:
```python
from haystack_integrations.components.retrievers.weaviate import WeaviateHybridRetriever
## Favor keyword search (good for exact matches)
retriever_keyword_heavy = WeaviateHybridRetriever(
document_store=document_store,
alpha=0.25,
)
## Balanced hybrid search
retriever_balanced = WeaviateHybridRetriever(document_store=document_store, alpha=0.5)
## Favor vector search (good for semantic similarity)
retriever_vector_heavy = WeaviateHybridRetriever(
document_store=document_store,
alpha=0.75,
)
## Override alpha at query time
result = retriever_balanced.run(
query="artificial intelligence",
query_embedding=embedding,
alpha=0.8,
)
```