集成:Couchbase
在 Haystack 中使用 Couchbase 数据库
目录
概述
由 deepset 将 Couchbase NoSQL 数据库与 Haystack v2.0 集成。在 Couchbase 中,向量搜索索引 用于索引文档嵌入和密集检索。
该库允许使用 Couchbase 作为 DocumentStore,并实现了所需的 协议 方法。您可以通过从 couchbase_haystack 包导入来实现来开始使用。
from couchbase_haystack import CouchbaseSearchDocumentStore
除了 CouchbaseSearchDocumentStore 之外,该库还包含以下 Haystack 组件,可在管道中使用。
- CouchbaseSearchEmbeddingRetriever:一个典型的 检索器组件,用于查询向量存储索引并查找相关文档。该组件使用
CouchbaseSearchDocumentStore查询嵌入。
couchbase-haystack 库使用 Python 驱动程序。
CouchbaseSearchDocumentStore 将文档存储为 Couchbase 中的 JSON 文档。嵌入作为文档的一部分存储,向量嵌入的索引和查询由 Couchbase 的专用 向量搜索索引 管理。
+-----------------------------+
| Couchbase Database |
+-----------------------------+
| |
| +----------------+ |
| | Data service | |
write_documents | +----------------+ |
+------------------------+----->| properties | |
| | | | |
+---------+--------------------+ | | embedding | |
| | | +--------+-------+ |
| CouchbaseSearchDocumentStore | | | |
| | | |index |
+---------+--------------------+ | | |
| | +--------+--------+ |
| | | Search service | |
| | +-----------------+ |
+----------------------->| | FTS | |
query_embeddings | | Vector Index | |
| | (for embedding) | |
| +-----------------+ |
| |
+-----------------------------+
在上面的图表中
- 数据服务:支持按键存储、设置和检索文档。基本上,文档是以键值对的形式存储的。
- 属性:作为文档一部分存储的文档 属性。
- 嵌入:文档的属性(在图中仅为清晰起见单独显示),其类型为
LIST[FLOAT]向量。 - 搜索服务:在此创建专门用于全文搜索和向量搜索的索引。搜索服务允许基于文本内容和向量嵌入进行高效查询和检索。
CouchbaseSearchDocumentStore 要求手动创建向量索引,可以通过 SDK 或 UI 进行。在写入文档之前,您应确保文档已通过提供的 嵌入器 进行嵌入。例如,可以在索引管道中使用 SentenceTransformersDocumentEmbedder 来计算文档嵌入,然后再将其写入 Couchbase。
安装
couchbase-haystack 可以像其他 Python 库一样使用 pip 进行安装。
pip install --upgrade pip # optional
pip install sentence-transformers # required in order to run pipeline examples given below
pip install couchbase-haystack
使用
运行 Couchbase
您需要运行一个 Couchbase 实例才能使用此包中的组件。有几种可用选项:
- Docker
- Couchbase Cloud - 完全托管的云服务
- Couchbase Server - 可在各种操作系统上安装
在本地启动数据库的最简单方法是使用 Docker 容器。
docker run \
--restart always \
--publish=8091-8096:8091-8096 --publish=11210:11210 \
--env COUCHBASE_ADMINISTRATOR_USERNAME=admin \
--env COUCHBASE_ADMINISTRATOR_PASSWORD=passw0rd \
couchbase:enterprise-7.6.2
在此示例中,容器是使用 Couchbase Server 版本 7.6.2 启动的。COUCHBASE_ADMINISTRATOR_USERNAME 和 COUCHBASE_ADMINISTRATOR_PASSWORD 环境变量设置了默认的身份验证凭据。
注意
假设您有一个正在运行的 Docker 容器,请导航至 https://:8091 以打开 Couchbase Web Console 并探索您的数据。
文档存储
安装好包并运行数据库后,您就可以开始使用 CouchbaseSearchDocumentStore,就像使用其他支持嵌入的文档存储一样。
from couchbase_haystack import CouchbaseSearchDocumentStore, CouchbasePasswordAuthenticator
from haystack.utils.auth import Secret
document_store = CouchbaseSearchDocumentStore(
cluster_connection_string=Secret.from_env_var("CB_CONNECTION_STRING"),
authenticator=CouchbasePasswordAuthenticator(
username=Secret.from_env_var("CB_USERNAME"),
password=Secret.from_env_var("CB_PASSWORD")
),
bucket = "haystack_bucket_name",
scope="haystack_scope_name",
collection="haystack_collection_name",
vector_search_index = "vector_search_index"
)
假设有一系列文档可用并且 Couchbase 数据库正在运行,您可以将它们写入/索引到 Couchbase 中,例如:
from haystack import Document
documents = [Document(content="Alice has been living in New York City for the past 5 years.")]
document_store.write_documents(documents)
如果您打算在写入文档之前获取嵌入,请使用以下代码:
from haystack import Document
# import one of the available document embedders
from haystack.components.embedders import SentenceTransformersDocumentEmbedder
documents = [Document(content="Alice has been living in New York City for the past 5 years.")]
document_embedder = SentenceTransformersDocumentEmbedder(model="sentence-transformers/all-MiniLM-L6-v2")
document_embedder.warm_up() # will download the model during first run
documents_with_embeddings = document_embedder.run(documents)
document_store.write_documents(documents_with_embeddings.get("documents"))
请确保嵌入模型生成的向量大小与在 Couchbase Vector Index 上设置的大小相同,例如,设置 embedding_dim=384 将符合“sentence-transformers/all-MiniLM-L6-v2”模型。
注意 大多数情况下,您将使用 Haystack Pipelines 来构建索引和查询 RAG 场景。
在调用 write_documents 后,了解 Haystack 文档如何在 Couchbase 中存储非常重要。
from random import random
sample_embedding = [random() for _ in range(384)] # using fake/random embedding for brevity here to simplify example
document = Document(
content="Alice has been living in New York City for the past 5 years.", embedding=sample_embedding, meta={"num_of_years": 5}
)
document.to_dict()
上面的代码将一个 Document 转换为字典,并将产生以下输出:
>>> output:
{
"id": "11c255ad10bff4286781f596a5afd9ab093ed056d41bca4120c849058e52f24d",
"content": "Alice has been living in New York City for the past 5 years.",
"dataframe": None,
"blob": None,
"score": None,
"embedding": [0.025010755222666936, 0.27502931836911926, 0.22321073814882275, ...], # vector of size 384
"num_of_years": 5,
}
在您使用 document_store.write_documents([document]) 写入文档后,字典中的数据将用于在 Couchbase 中创建文档。您可以使用 Cypher 查询它,例如 MATCH (doc:Document) RETURN doc。以下是 Couchbase 中的一个 JSON 文档:
{
"id": "11c255ad10bff4286781f596a5afd9ab093ed056d41bca4120c849058e52f24d",
"embedding": [0.6394268274307251, 0.02501075528562069,0.27502933144569397, ...], // vector of size 384
"content": "Alice has been living in New York City for the past 5 years.",
"meta": {
"num_of_years": 5
}
}
CouchbaseSearchDocumentStore 接受的参数的完整列表可以在 API 文档 中找到。
索引文档
使用 Haystack,您可以使用 DocumentWriter 组件将文档写入 Document Store。在下面的示例中,我们构建了一个管道,使用 CouchbaseDocumentStore 将文档写入 Couchbase。
from haystack import Document
from haystack.components.embedders import SentenceTransformersDocumentEmbedder
from haystack.components.writers import DocumentWriter
from haystack.pipeline import Pipeline
from haystack.utils.auth import Secret
from couchbase_haystack import CouchbaseSearchDocumentStore, CouchbasePasswordAuthenticator
documents = [Document(content="This is document 1"), Document(content="This is document 2")]
document_store = CouchbaseSearchDocumentStore(
cluster_connection_string=Secret.from_env_var("CB_CONNECTION_STRING"),
authenticator=CouchbasePasswordAuthenticator(
username=Secret.from_env_var("CB_USERNAME"),
password=Secret.from_env_var("CB_PASSWORD")
),
bucket = "haystack_bucket_name",
scope="haystack_scope_name",
collection="haystack_collection_name",
vector_search_index = "vector_search_index"
)
embedder = SentenceTransformersDocumentEmbedder(model="sentence-transformers/all-MiniLM-L6-v2")
document_writer = DocumentWriter(document_store=document_store)
indexing_pipeline = Pipeline()
indexing_pipeline.add_component(instance=embedder, name="embedder")
indexing_pipeline.add_component(instance=document_writer, name="writer")
indexing_pipeline.connect("embedder", "writer")
indexing_pipeline.run({"embedder": {"documents": documents}})
>>> output:
`{'writer': {'documents_written': 2}}`
检索文档
CouchbaseSearchEmbeddingRetriever 组件可用于通过使用嵌入式查询查询向量索引来从 Couchbase 检索文档。下面是一个使用查询嵌入来查找文档的管道:
from typing import List
from haystack import Document, Pipeline
from haystack.components.embedders import SentenceTransformersDocumentEmbedder, SentenceTransformersTextEmbedder
from haystack.utils.auth import Secret
from couchbase_haystack.document_store import CouchbaseSearchDocumentStore, CouchbasePasswordAuthenticator
from couchbase_haystack.component.retriever import CouchbaseSearchEmbeddingRetriever
document_store = CouchbaseSearchDocumentStore(
cluster_connection_string=Secret.from_env_var("CB_CONNECTION_STRING"),
authenticator=CouchbasePasswordAuthenticator(
username=Secret.from_env_var("CB_USERNAME"),
password=Secret.from_env_var("CB_PASSWORD")
),
bucket = "haystack_bucket_name",
scope="haystack_scope_name",
collection="haystack_collection_name",
vector_search_index = "vector_search_index"
)
documents = [
Document(content="Alice has been living in New York City for the past 5 years.", meta={"num_of_years": 5, "city": "New York"}),
Document(content="John moved to Los Angeles 2 years ago and loves the sunny weather.", meta={"num_of_years": 2, "city": "Los Angeles"}),
]
# Same model is used for both query and Document embeddings
model_name = "sentence-transformers/all-MiniLM-L6-v2"
document_embedder = SentenceTransformersDocumentEmbedder(model=model_name)
document_embedder.warm_up()
documents_with_embeddings = document_embedder.run(documents)
document_store.write_documents(documents_with_embeddings.get("documents"))
print("Number of documents written: ", document_store.count_documents())
pipeline = Pipeline()
pipeline.add_component("text_embedder", SentenceTransformersTextEmbedder(model=model_name))
pipeline.add_component("retriever", CouchbaseSearchEmbeddingRetriever(document_store=document_store))
pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
result = pipeline.run(
data={
"text_embedder": {"text": "What cities do people live in?"},
"retriever": {
"top_k": 5
},
}
)
documents: List[Document] = result["retriever"]["documents"]
>>> output:
[Document(id=3e35fa03aff6e3c45e6560f58adc4fde3c436c111a8809c30133b5cb492e8694, content: 'Alice has been living in New York City for the past 5 years.', meta: {'num_of_years': 5, 'city': 'New York'}, score: 0.36796408891677856, embedding: "embedding": vector of size 384), Document(id=ca4d7d7d7ff6c13b950a88580ab134b2dc15b48a47b8f571a46b354b5344e5fa, content: 'John moved to Los Angeles 2 years ago and loves the sunny weather.', meta: {'num_of_years': 2, 'city': 'Los Angeles'}, score: 0.3126790523529053, embedding: vector of size 384)]
更多示例
您可以在实现 仓库 中找到更多示例。
- indexing_pipeline.py - 从远程 HTTP 位置索引文本文件(文档)。
-
rag_pipeline.py - 生成式问答 RAG 管道,使用
CouchbaseSearchEmbeddingRetriever从 Couchbase 文档存储中获取文档,并使用 HuggingFaceAPIGenerator 回答问题。
许可证
couchbase-haystack 在 MIT 许可证条款下分发。
