在 Haystack 中使用 AlloyDB:AlloyDBDocumentStore 与向量/关键词检索组件实战指南

发布时间:2026/9/13 8:28:43
在 Haystack 中使用 AlloyDB:AlloyDBDocumentStore 与向量/关键词检索组件实战指南 在 Haystack 中使用 AlloyDBAlloyDBDocumentStore 与向量/关键词检索组件实战指南【免费下载链接】haystackOpen-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows with explicit control over retrieval, routing, memory, and generation. Built for scalable agents, RAG, multimodal applications, semantic search, and conversational systems.项目地址: https://gitcode.com/GitHub_Trending/ha/haystack本篇技术指南围绕 Haystack 生态中的alloydb-haystack集成展开系统讲解AlloyDBDocumentStore、AlloyDBEmbeddingRetriever与AlloyDBKeywordRetriever三个核心组件的初始化参数、检索行为与元数据过滤能力。读完本文你将掌握如何在 Haystack Pipeline 中接入 Google Cloud AlloyDB基于 pgvector 的托管式 PostgreSQL 兼容数据库构建语义检索、关键词全文检索以及两者混合的 RAG 应用并理解底层 SQL 与索引机制。文章以 docs-website/reference_versioned_docs/version-2.19/integrations-api/alloydb.md 的 API 说明为主体骨架结合仓库内 AlloyDBDocumentStore 使用指南 等配套文档与源码细节进行纵深扩充。一、AlloyDB 集成概览为什么选择 AlloyDB 作为 Haystack 的 Document StoreAlloyDBDocumentStore是一个由 Google Cloud AlloyDB 支撑的 Document Store 实现。AlloyDB 是 Google Cloud 提供的全托管、与 PostgreSQL 兼容的数据库服务而该 Document Store 借助pgvector 扩展完成向量相似度检索对应官方文档Uses the pgvector extension for vector search的说明。从集成架构上看这个 Document Store 有三个关键特性安全的连接方式连接通过 AlloyDB Python Connector 处理内置 TLS 加密与基于 IAM 的授权无需手动管理 SSL 证书、配置防火墙规则或维护 IP 白名单三种检索能力支持嵌入向量检索embedding retrieval、关键词检索keyword retrieval与元数据过滤metadata filtering可覆盖语义搜索与词法搜索两类场景懒连接与自动建表与 AlloyDB 的连接在首次使用时才建立存储 Haystack 文档的表若不存在会自动创建。配套的使用文档明确说明AlloyDBDocumentStore支持嵌入检索、关键词检索与元数据过滤三类能力完整入门说明见 docs-website/docs/document-stores/alloydbdocumentstore.mdx。二、安装与前置准备2.1 安装集成包在安装alloydb-haystack集成之前需要先完成 AlloyDB 集群与实例的创建可参照官方 AlloyDB quickstart 指引。随后安装集成包pip install alloydb-haystack如果要在示例中使用 Sentence Transformers 嵌入器SentenceTransformersDocumentEmbedder/SentenceTransformersTextEmbedder还需要安装pip install sentence-transformers-haystack2.2 认证与环境变量AlloyDBDocumentStore基于 Haystack 的 Secret 机制 读取连接凭据。instance_uri、user、password三个参数的默认值分别从以下环境变量读取ALLOYDB_INSTANCE_URIAlloyDB 实例 URI格式为projects/PROJECT/locations/REGION/clusters/CLUSTER/instances/INSTANCEALLOYDB_USER数据库用户。若使用 IAM 数据库认证应使用服务账号邮箱去掉.gserviceaccount.com后缀或完整的 IAM 用户邮箱ALLOYDB_PASSWORD数据库密码当enable_iam_authTrue时不需要。export ALLOYDB_INSTANCE_URIprojects/MY_PROJECT/locations/MY_REGION/clusters/MY_CLUSTER/instances/MY_INSTANCE export ALLOYDB_USERmy-db-user export ALLOYDB_PASSWORDmy-db-password若希望改用 IAM 认证而非密码可设置enable_iam_authTrue并为 IAM 主体授予 AlloyDB Client 角色。IAM 认证模式下password参数会被忽略同时要求该 IAM 主体已被创建为 IAM 数据库用户。值得说明的是从源码签名看Secret.from_env_var(ALLOYDB_PASSWORD, strictFalse)密码环境变量采用了非严格模式这意味着即使未设置该环境变量初始化过程也不会直接报错——这与ALLOYDB_INSTANCE_URI、ALLOYDB_USER的严格模式strict默认开启形成对比。这一细节与 Haystack 的 Secret 管理文档 中“环境变量型 Secret 可序列化、只保存变量名不保存值”的设计一脉相承当 Pipeline 序列化为 YAML 时仅记录环境变量名避免敏感信息落盘。三、AlloyDBDocumentStore核心初始化参数详解AlloyDBDocumentStore的完整构造函数签名如下__init__( *, instance_uri: Secret Secret.from_env_var(ALLOYDB_INSTANCE_URI), user: Secret Secret.from_env_var(ALLOYDB_USER), password: Secret Secret.from_env_var(ALLOYDB_PASSWORD, strictFalse), db: str postgres, enable_iam_auth: bool False, ip_type: Literal[PRIVATE, PUBLIC, PSC] PRIVATE, create_extension: bool True, schema_name: str public, table_name: str haystack_documents, language: str english, embedding_dimension: int 768, vector_function: Literal[ cosine_similarity, inner_product, l2_distance ] cosine_similarity, recreate_table: bool False, search_strategy: Literal[ exact_nearest_neighbor, hnsw ] exact_nearest_neighbor, hnsw_recreate_index_if_exists: bool False, hnsw_index_creation_kwargs: dict[str, int] | None None, hnsw_index_name: str haystack_hnsw_index, hnsw_ef_search: int | None None, keyword_index_name: str haystack_keyword_index ) - None下表汇总了全部参数的作用、默认值与注意事项参数默认值说明instance_uriSecret.from_env_var(ALLOYDB_INSTANCE_URI)AlloyDB 实例 URI格式projects/PROJECT/locations/REGION/clusters/CLUSTER/instances/INSTANCEuserSecret.from_env_var(ALLOYDB_USER)数据库用户IAM 认证时使用服务账号邮箱去.gserviceaccount.com或完整 IAM 用户邮箱passwordSecret.from_env_var(ALLOYDB_PASSWORD, strictFalse)数据库密码enable_iam_authTrue时忽略dbpostgres要连接的数据库名enable_iam_authFalse是否使用 IAM 数据库认证替代密码为True时忽略passwordIAM 主体需被授予 AlloyDB Client 角色并创建 IAM 数据库用户ip_typePRIVATE连接使用的 IP 类型PRIVATE默认走私有 VPC IP、PUBLIC公网 IP、PSCPrivate Service Connectcreate_extensionTrue若 pgvector 扩展不存在是否自动创建创建扩展可能需要超级用户权限设为False时必须确保扩展已预先安装否则报错schema_namepublic建表所在 schema该 schema 必须已存在table_namehaystack_documents存储 Haystack 文档的表名languageenglish关键词检索中解析查询与文档内容所用语言可用SELECT cfgname FROM pg_ts_config;查看数据库支持的语言列表embedding_dimension768嵌入向量的维度vector_functioncosine_similarity向量相似度函数可选cosine_similarity、inner_product、l2_distancerecreate_tableFalse若表已存在是否重建search_strategyexact_nearest_neighbor检索策略精确最近邻或hnsw近似最近邻hnsw_recreate_index_if_existsFalse仅在search_strategyhnsw时生效HNSW 索引已存在时是否重建hnsw_index_creation_kwargsNone仅在search_strategyhnsw时生效传给 HNSW 索引创建的额外参数合法参数为m与ef_construction详见 pgvector 文档hnsw_index_namehaystack_hnsw_indexHNSW 索引名hnsw_ef_searchNone仅在search_strategyhnsw时生效查询时的ef_search参数keyword_index_namehaystack_keyword_index关键词 GIN 索引名3.1 向量相似度函数的三选一vector_function决定向量检索时如何度量相似度这一选择同时影响索引的构建cosine_similarity默认与inner_product属于相似度函数得分越高文档与查询越相似l2_distance返回向量间的直线距离得分越小文档越相似。重要提醒当使用hnsw检索策略时创建的 HNSW 索引依赖初始化时传入的vector_function。后续查询若想利用该索引必须持续使用相同的向量相似度函数否则索引将无法生效。这一点在vector_function与search_strategy两个参数的说明中均有强调。3.2 检索策略精确最近邻 vs HNSWsearch_strategy提供两种嵌入检索策略exact_nearest_neighbor默认精确最近邻搜索召回完美perfect recall但在文档量很大时速度可能较慢hnsw近似最近邻搜索以少量精度换取速度推荐用于大规模文档场景。使用hnsw时可以通过hnsw_index_creation_kwargsm与ef_construction调优索引构建过程并通过hnsw_ef_search控制查询时的搜索宽度hnsw_recreate_index_if_exists控制索引已存在时是否重建。3.3 基础用法示例以下示例创建 Document Store 并写入两个文档含 768 维嵌入from haystack import Document from haystack_integrations.document_stores.alloydb import AlloyDBDocumentStore document_store AlloyDBDocumentStore( dbmy-database, embedding_dimension768, vector_functioncosine_similarity, recreate_tableTrue, ) document_store.write_documents( [ Document(contentThis is first, embedding[0.1] * 768), Document(contentThis is second, embedding[0.3] * 768), ], ) print(document_store.count_documents())连接在首次使用时懒建立文档表不存在时自动创建。写入文档时可通过policy参数DuplicatePolicy控制重复文档处理方式DuplicatePolicy枚举位于 haystack/document_stores/types/policy.py取值包括NONE、SKIP跳过、OVERWRITE覆盖、FAIL默认重复时报错。write_documents在文档 id 已存在且策略为FAIL或未指定时抛出DuplicateDocumentError传入非Document对象抛出ValueError。要为用户文档生成嵌入可使用 Document Embedder例如仓库文档中推荐的SentenceTransformersDocumentEmbedder。四、AlloyDBEmbeddingRetriever基于嵌入相似度的向量检索4.1 初始化参数__init__( *, document_store: AlloyDBDocumentStore, filters: dict[str, Any] | None None, top_k: int 10, vector_function: ( Literal[cosine_similarity, inner_product, l2_distance] | None ) None, filter_policy: str | FilterPolicy FilterPolicy.REPLACE ) - None参数默认值说明document_store必填AlloyDBDocumentStore实例必须与该检索器配套使用filtersNone应用于检索结果的元数据过滤器top_k10返回文档的最大数量vector_functionNone相似度函数覆盖 Document Store 上设置的vector_functionNone时沿用 Document Store 的配置filter_policyFilterPolicy.REPLACE查询时过滤器组合策略见 4.3若document_store不是AlloyDBDocumentStore实例__init__抛出ValueError。4.2 run 方法run( query_embedding: list[float], filters: dict[str, Any] | None None, top_k: int | None None, vector_function: ( Literal[cosine_similarity, inner_product, l2_distance] | None ) None, ) - dict[str, list[Document]]query_embedding必填查询的向量表示float 列表filters运行时过滤器与初始化过滤器的组合方式由filter_policy决定top_k覆盖初始化时的top_kvector_function覆盖初始化时的vector_function。返回值为字典键documents对应检索到的文档列表。需要特别注意的是嵌入检索依赖的若干关键参数必须在初始化AlloyDBDocumentStore时定义包括embedding_dimension、vector_function以及检索策略exact_nearest_neighbor或hnsw。因此调整这些参数需要回到 Document Store 层面重新初始化。4.3 filter_policy初始化过滤器与运行时过滤器的组合策略filter_policy控制查询时过滤器如何生效其定义位于 haystack/document_stores/types/filter_policy.pyclass FilterPolicy(Enum): # Runtime filters replace init filters during retriever run invocation. REPLACE replace # Runtime filters are merged with init filters, with runtime filters overwriting init values. MERGE mergeFilterPolicy.REPLACE默认运行时传入的 filters 直接替换初始化时设置的 filtersFilterPolicy.MERGE运行时 filters 与初始化 filters 合并运行时值覆盖初始化值。4.4 独立使用与 Pipeline 集成独立使用需先设置上文的环境变量此处用假向量简化示例from haystack_integrations.document_stores.alloydb import AlloyDBDocumentStore from haystack_integrations.components.retrievers.alloydb import ( AlloyDBEmbeddingRetriever, ) document_store AlloyDBDocumentStore() retriever AlloyDBEmbeddingRetriever(document_storedocument_store) ## using a fake vector to keep the example simple retriever.run(query_embedding[0.1] * 768)在语义检索 Pipeline 中的完整用法先由SentenceTransformersDocumentEmbedder为文档生成嵌入并写入再构建“文本嵌入器 → 检索器”的查询管线from haystack import Document, Pipeline from haystack.document_stores.types import DuplicatePolicy from haystack_integrations.components.embedders.sentence_transformers import ( SentenceTransformersTextEmbedder, SentenceTransformersDocumentEmbedder, ) from haystack_integrations.document_stores.alloydb import AlloyDBDocumentStore from haystack_integrations.components.retrievers.alloydb import ( AlloyDBEmbeddingRetriever, ) document_store AlloyDBDocumentStore( embedding_dimension768, vector_functioncosine_similarity, recreate_tableTrue, ) documents [ Document(contentThere are over 7,000 languages spoken around the world today.), Document( contentElephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors., ), Document( contentIn 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), policyDuplicatePolicy.OVERWRITE, ) query_pipeline Pipeline() query_pipeline.add_component(text_embedder, SentenceTransformersTextEmbedder()) query_pipeline.add_component( retriever, AlloyDBEmbeddingRetriever(document_storedocument_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])在 RAG 管线中AlloyDBEmbeddingRetriever的典型位置是Text Embedder 之后、PromptBuilder之前语义搜索管线的末端组件或在抽取式 QA 管线中位于 Text Embedder 之后、TransformersExtractiveReader之前。五、AlloyDBKeywordRetriever基于 PostgreSQL 全文检索的关键词检索5.1 工作原理AlloyDBKeywordRetriever通过 PostgreSQL 全文检索to_tsvector/plainto_tsquery查找文档并使用ts_rank_cd对结果排序。排序综合考虑查询词在文档中出现的频率、查询词彼此之间的接近程度以及它们出现的文档位置的重要性详见 PostgreSQL text search ranking 文档。需要注意与ElasticsearchBM25Retriever等组件不同该检索器默认不做模糊搜索因此需要精心构造查询词避免返回零结果。关键词解析所用的语言由AlloyDBDocumentStore的language参数决定默认english。可通过 SQL 查询查看当前数据库支持的语言列表SELECT cfgname FROM pg_ts_config;5.2 初始化与 run 方法__init__( *, document_store: AlloyDBDocumentStore, filters: dict[str, Any] | None None, top_k: int 10, filter_policy: str | FilterPolicy FilterPolicy.REPLACE ) - None参数默认值说明document_store必填AlloyDBDocumentStore实例filtersNone应用于检索结果的元数据过滤器top_k10返回文档的最大数量filter_policyFilterPolicy.REPLACE运行时过滤器与初始化过滤器的组合策略同 4.3run方法run( query: str, filters: dict[str, Any] | None None, top_k: int | None None ) - dict[str, list[Document]]query必填关键词查询字符串filters运行时过滤器top_k覆盖初始化时的top_k。5.3 独立使用from haystack_integrations.document_stores.alloydb import AlloyDBDocumentStore from haystack_integrations.components.retrievers.alloydb import ( AlloyDBKeywordRetriever, ) document_store AlloyDBDocumentStore() retriever AlloyDBKeywordRetriever(document_storedocument_store) retriever.run(querymy nice query)5.4 在 RAG Pipeline 中使用以下示例构建一个“关键词检索 → Prompt 构建 → LLM 生成 → 答案组装”的 RAG 管线。运行前提设置OPENAI_API_KEY环境变量用于OpenAIChatGenerator并设置ALLOYDB_INSTANCE_URI、ALLOYDB_USER、ALLOYDB_PASSWORD三个环境变量。from haystack import Document, Pipeline 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.dataclasses import ChatMessage from haystack.document_stores.types import DuplicatePolicy from haystack_integrations.document_stores.alloydb import AlloyDBDocumentStore from haystack_integrations.components.retrievers.alloydb import ( AlloyDBKeywordRetriever, ) ## Create a RAG query pipeline 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:, ), ] document_store AlloyDBDocumentStore( languageenglish, # this parameter influences text parsing for keyword retrieval recreate_tableTrue, ) documents [ Document(contentThere are over 7,000 languages spoken around the world today.), Document( contentElephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors., ), Document( contentIn 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(documentsdocuments, policyDuplicatePolicy.SKIP) retriever AlloyDBKeywordRetriever(document_storedocument_store) rag_pipeline Pipeline() rag_pipeline.add_component(nameretriever, instanceretriever) rag_pipeline.add_component( instanceChatPromptBuilder( templateprompt_template, required_variables{question, documents}, ), nameprompt_builder, ) rag_pipeline.add_component(instanceOpenAIChatGenerator(), namellm) rag_pipeline.add_component(instanceAnswerBuilder(), nameanswer_builder) rag_pipeline.connect(retriever, prompt_builder.documents) rag_pipeline.connect(prompt_builder.prompt, llm.messages) rag_pipeline.connect(llm.replies, answer_builder.replies) 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])六、元数据过滤支持的运算符与 NOT 限制6.1 完整支持的运算符AlloyDBDocumentStore完整支持以下比较运算符与逻辑运算符比较运算符、!、、、、、in、not in、like、not like逻辑运算符AND、OR。其中like/not like是对标准 Haystack 过滤语法的 PostgreSQL 专有扩展映射到 SQL 的LIKE/NOT LIKE模式匹配运算符。标准的 Haystack 过滤语法详见 docs-website/docs/concepts/metadata-filtering.mdx。6.2 NOT 运算符的限制与改写策略NOT逻辑运算符不受支持这是使用该 Document Store 时最容易踩的坑。官方文档给出的改写思路是由于每个比较运算符都有对应的取反形式/!、in/not in、like/not like任何仅围绕单个条件使用NOT的过滤器都可以通过反转比较运算符来表达若要取反嵌套的AND/OR组则运用德摩根定律——例如NOT (A AND B)改写为(NOT A) OR (NOT B)其中的每个NOT A/NOT B再用反转后的比较运算符表达。# 不支持{operator: NOT, conditions: [...]} # 应改写为 { operator: OR, conditions: [ {field: meta.type, operator: !, value: article}, {field: meta.genre, operator: not in, value: [economy, politics]}, ], }6.3 在 Document Store 方法中的过滤行为filter_documents(filters)返回匹配过滤器的文档filters不是字典时抛TypeError语法无效时抛ValueErrordelete_by_filter(filters)删除匹配过滤器的文档返回删除数量update_by_filter(filters, meta)更新匹配过滤器文档的元数据字段返回更新数量count_documents_by_filter(filters)返回匹配过滤器的文档数量count_unique_metadata_by_filter(filters, metadata_fields)对每个指定元数据字段统计唯一值数量字段名可带或不带meta.前缀delete_documents(document_ids)按 id 列表删除delete_all_documents()清空所有文档。七、元数据字段自省与序列化AlloyDBDocumentStore还提供一组元数据自省方法便于构建动态过滤界面或调试数据get_metadata_fields_info()由于元数据存储在 JSONB 字段中该方法通过分析实际数据推断字段类型。返回示例{category: {type: text}, priority: {type: integer}}get_metadata_field_min_max(field)返回某元数据字段的最小值与最大值。数值字段integer、real返回数值型 min/max文本等非数值字段使用C排序规则返回字典序 min/max字段无值或存储为空时返回{min: None, max: None}get_metadata_field_unique_values(metadata_field, search_termNone, from_0, size10, filtersNone)返回指定元数据字段的唯一值列表及总数支持大小写不敏感的子串匹配search_term、0 基分页from_/size以及过滤器约束。返回(唯一值列表, 唯一值总数)元组。序列化方面to_dict()将组件序列化为字典含秘密信息时只保留环境变量名from_dict(data)从字典反序列化还原组件两个检索器与 Document Store 均实现了这一对方法保证 Pipeline 可以安全地持久化到 YAML 并在加载后还原。八、资源管理三个组件都实现了close()方法AlloyDBDocumentStore.close()释放底层关联的同步资源AlloyDBEmbeddingRetriever.close()与AlloyDBKeywordRetriever.close()释放底层 Document Store 的同步资源。另外delete_table()可删除存储 Haystack 文档的表表名由初始化时的schema_name与table_name决定。在需要重置数据或升级表结构配合recreate_tableTrue时非常有用。九、常见问题与最佳实践HNSW 索引失效使用hnsw检索策略时索引依赖创建时的vector_function后续查询必须使用相同相似度函数。检索器层面的vector_function覆盖参数需谨慎使用避免与 Document Store 的索引配置不一致。零结果检索AlloyDBKeywordRetriever默认无模糊匹配查询词拼写偏差可能导致空结果需精心构造查询或考虑结合AlloyDBEmbeddingRetriever做混合检索兜底。NOT过滤器报错遇到包含NOT的过滤器时先按 6.2 的德摩根改写思路转换为!/not in/not like组合。embedding_dimension不一致Document Store 建表依赖embedding_dimension写入的文档嵌入维度必须与之一致如示例中的 768 维否则写入或检索会失败。IAM 认证enable_iam_authTrue时无需密码环境变量但需确保 IAM 主体已授予 AlloyDB Client 角色并创建为 IAM 数据库用户且user使用对应的服务账号或 IAM 用户标识。大规模数据选型文档量大时建议切换search_strategyhnsw并调优hnsw_index_creation_kwargsm、ef_construction与hnsw_ef_search在召回精度与查询延迟间取得平衡。十、配套文档导航AlloyDB 集成 API 参考当前版本本文主体内容的权威 API 说明来源AlloyDBDocumentStore 使用指南安装、认证、初始化与检索策略的完整入门AlloyDBEmbeddingRetriever 组件文档嵌入检索器在 Pipeline 中的用法与位置AlloyDBKeywordRetriever 组件文档关键词检索器与 RAG 示例Secret 管理环境变量型 Secret 与序列化安全说明元数据过滤Haystack 通用过滤语法与嵌套过滤器示例源码佐证DuplicatePolicy 定义、FilterPolicy 定义。通过上述内容你可以在 Haystack 中完整落地“AlloyDB 向量语义检索 PostgreSQL 全文关键词检索 元数据过滤”的组合方案并将其嵌入 RAG、语义搜索与抽取式问答 Pipeline。【免费下载链接】haystackOpen-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows with explicit control over retrieval, routing, memory, and generation. Built for scalable agents, RAG, multimodal applications, semantic search, and conversational systems.项目地址: https://gitcode.com/GitHub_Trending/ha/haystack创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考