LlamaIndex 实战:使用 MongoDBAtlasBM25Retriever 在 MongoDB Atlas 上构建 BM25 关键词检索
2026/9/11 1:44:30 网站建设 项目流程

LlamaIndex 实战:使用 MongoDBAtlasBM25Retriever 在 MongoDB Atlas 上构建 BM25 关键词检索

【免费下载链接】llama_indexLlamaIndex is the leading document agent and OCR platform项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index

导读

MongoDB Atlas 自带的全文检索(Atlas Search)提供了开箱即用的 BM25 相关性评分能力,而 LlamaIndex 生态通过MongoDBAtlasBM25Retriever将其封装为标准的 LlamaIndex Retriever。本篇文章以 docs/api_reference/api_reference/retrievers/mongodb_atlas_bm25_retriever.md 中指向的核心类为主线,结合仓库内该集成的完整源码、依赖声明与测试用例,系统讲解其安装方式、构造参数、内部聚合管道与节点重建原理。读完本文,你将掌握如何在 LlamaIndex 应用中直接以 MongoDB 文档为数据源,通过一条retrieve()调用完成基于 BM25 的关键词召回,并理解其与向量检索在架构定位上的差异。

一、MongoDBAtlasBM25Retriever 是什么

MongoDBAtlasBM25Retriever是 LlamaIndex 为 MongoDB Atlas 提供的 BM25 检索器集成,位于仓库的llama-index-integrations/retrievers/llama-index-retrievers-mongodb-atlas-bm25-retriever/目录下。与同为 Atlas 家族的MongoDBAtlasVectorSearch不同,后者是一个VectorStore(负责存储与向量检索),而前者是一个标准的BaseRetriever子类,专责于"给定查询字符串,返回带 BM25 相关性分数的节点列表"。

从源码继承关系看(base.py),该类直接继承自 LlamaIndex 核心的BaseRetriever(定义于 base_retriever.py),因此它天然获得核心框架提供的retrieve()公共入口、回调(callback)、dispatcher span 追踪等能力。测试用例 test_retrievers_bm25_retriever.py 中即通过检查MongoDBAtlasBM25Retriever.__mro__断言其基类链中包含BaseRetriever,从侧面印证了这一设计约定。

二、安装与依赖环境

该集成以独立 Python 包的形式发布,包名为llama-index-retrievers-mongodb-atlas-bm25-retriever。根据 pyproject.toml 声明的依赖约束:

  • pymongo>=4.6.1,<5:MongoDB 官方 Python 驱动,是连接 Atlas 与执行聚合管道的底层依赖;
  • llama-index-core>=0.13.0,<0.15:提供BaseRetrieverNodeWithScoreQueryBundleTextNode等核心类型;
  • requires-python = ">=3.10,<4.0":要求 Python 3.10 及以上版本。

安装方式为标准的 pip 安装:

pip install llama-index-retrievers-mongodb-atlas-bm25-retriever

源码实现中(base.py)对pymongo做了延迟导入检查:若环境中缺少pymongo,会抛出ImportError并提示pip install pymongo,因此在安装上述集成包时请确保pymongo一并就绪。

三、快速上手:三步完成 BM25 检索

集成包的 README(README.md)给出了一段可直接运行的示例。它基于pymongo.MongoClient建立连接,然后构造检索器并调用retrieve

from llama_index.retrievers.mongodb_atlas_bm25_retriever import MongoDBAtlasBM25Retriever import pymongo mongodb_client = pymongo.MongoClient(mongo_uri) retriever = MongoDBAtlasBM25Retriever( mongodb_client=mongodb_client, db_name="vectorstore", collection_name="vector_collection", index_name="index_vector_collection", ) nodes = retriever.retrieve("retrieve_query")

其中mongo_uri是连接串(形如mongodb+srv://user:pass@cluster.mongodb.net/),db_namecollection_name对应你在 Atlas 中已存在的数据库与集合,index_name则是你在 Atlas Search 中预先创建好的全文索引名称。retrieve()的入参可以是普通字符串,也可以是QueryBundle对象——核心的BaseRetriever.retrieve(base_retriever.py)会自动完成字符串到QueryBundle的包装,并交由子类实现的_retrieve完成真正的检索逻辑。

四、构造参数详解

MongoDBAtlasBM25Retriever.__init__的全部参数及语义(依据 base.py)整理如下:

参数默认值说明
mongodb_clientNone已创建的pymongo.MongoClient实例。若不传,则回退读取环境变量MONGO_URI自动创建客户端
db_name"default_db"MongoDB 数据库名
collection_name"default_collection"MongoDB 集合名
index_name"default"Atlas Search 全文索引名(对应$search阶段中的index字段)
text_key"text"存放检索文本的文档字段名
metadata_key"metadata"存放节点元数据的文档字段名
similarity_top_kDEFAULT_SIMILARITY_TOP_K(值为 2)返回的命中节点数量上限

关于默认值需要特别说明两点:

  1. similarity_top_k的默认值并非硬编码,而是引用核心常量DEFAULT_SIMILARITY_TOP_K。该常量定义于 constants.py,取值为2。也就是说,若不显式指定,检索默认只返回 2 条结果,实际使用中通常需要按业务显式调大。
  2. 客户端创建的双路径逻辑:当mongodb_clientNone时,源码会检查环境变量MONGO_URI是否存在,不存在则抛出ValueError;存在则以该 URI 新建客户端,并通过DriverInfo(name="llama-index", version=version("llama-index"))向 MongoDB 服务端上报驱动标识,便于 Atlas 侧统计与排障。

五、底层原理:一次 BM25 检索的聚合管道

MongoDBAtlasBM25Retriever._retrieve(base.py)的核心是构造并执行一条 MongoDB 聚合管道(aggregation pipeline),完整还原如下:

pipeline = [ { "$search": { "index": self._index_name, "text": {"query": query, "path": self._text_key}, } }, {"$addFields": {"score": {"$meta": "searchScore"}}}, {"$sort": {"score": -1}}, {"$limit": self._similarity_top_k}, ] results = list(self._collection.aggregate(pipeline))

管道四个阶段各自的作用:

  1. $search:调用 Atlas Search 的text查询,index指定搜索索引名,query为查询字符串,path指定要检索的文本字段(即构造参数text_key)。BM25 相关性评分在这一步由 Atlas Search 引擎完成;
  2. $addFields:通过$meta: "searchScore"将 Atlas Search 计算的 BM25 分数写入新增的score字段;
  3. $sort:按score降序排列,实现相关性从高到低;
  4. $limit:截取前similarity_top_k条,控制返回规模。

随后,代码对每个命中文档执行self._collection.find_one({"_id": result["_id"]})回查完整文档,再进入节点重建环节。整条链路完全在 MongoDB 侧完成排序与截断,LlamaIndex 侧只负责组装管道与解析结果,因此检索性能与数据规模主要由 Atlas Search 的索引与集群规格决定。

六、从 MongoDB 文档到 LlamaIndex 节点:元数据重建机制

检索结果需要还原为 LlamaIndex 的Node才能被下游的RetrieverQueryEngine、响应合成器等组件消费。_retrieve中的重建逻辑(base.py)采用"优先精确还原、失败降级兜底"的两级策略:

  • 第一级(精确还原):读取文档中metadata字段里的_node_content,调用核心工具函数metadata_dict_to_node(定义于 vector_stores/utils.py)将序列化的节点 JSON 还原为原始的BaseNode子类对象(如TextNodeIndexNode),随后用node.set_content(doc["text"])回填文本内容。这要求数据在写入集合时遵循 LlamaIndex 的节点序列化约定(_node_content中保存node.model_dump(mode="json")的结果)。
  • 第二级(降级兜底):当metadata_dict_to_node_node_content缺失或损坏抛出异常时,捕获后手动构造TextNode,其textid_metadata分别取自文档的text字段、id字段与metadata字段,并尽量从node_content中恢复start_char_idxend_char_idxrelationships等字段。

最终,每个节点与管道返回的score一起包装为NodeWithScore(node=node, score=result["score"]),以列表形式返回给调用方。这一设计意味着:即使集合中的文档并非由 LlamaIndex 写入(没有_node_content),检索器也能降级构造出可用的TextNode,保证了与外部数据源的兼容性。

七、在查询引擎中组合使用

由于MongoDBAtlasBM25Retriever实现了标准的BaseRetriever接口,它可以直接参与 LlamaIndex 的查询管线。典型用法是与查询引擎组合,将 BM25 召回结果交给 LLM 生成答案:

from llama_index.core.query_engine import RetrieverQueryEngine query_engine = RetrieverQueryEngine.from_args(retriever=retriever) response = query_engine.query("你的查询问题")

也可以与向量检索器结合构成混合检索(hybrid search):将MongoDBAtlasBM25RetrieverMongoDBAtlasVectorSearch构建的向量检索器分别召回后,通过QueryFusionRetriever或自定义的合并后处理器融合两者的结果,从而兼顾关键词精确匹配与语义相似度召回。仓库中的 retrievers 示例目录 提供了多种检索器组合的 Notebook 参考。

八、前提条件与注意事项

  • Atlas Search 索引需预先创建index_name指向的全文索引必须先在 MongoDB Atlas 控制台(或通过 Atlas API)创建,且索引配置中的path应与text_key保持一致,否则$search阶段会报错;
  • 连接方式二选一:要么显式传入mongodb_client,要么保证环境变量MONGO_URI可用,二者都不满足时会直接抛出ValueError
  • 默认 top_k 偏小DEFAULT_SIMILARITY_TOP_K仅为 2,生产场景建议显式传入similarity_top_k
  • 字段命名约定:若你的文档中文本字段不叫text、元数据字段不叫metadata,请通过text_keymetadata_key对齐,否则节点重建的降级路径可能拿不到预期内容;
  • 版本兼容:集成包要求 Python ≥ 3.10、pymongo>=4.6.1,<5llama-index-core>=0.13.0,<0.15,请确保环境中版本满足约束。

小结

MongoDBAtlasBM25Retriever以极小的代码面(一个类、一条聚合管道)把 MongoDB Atlas Search 的 BM25 能力无缝接入 LlamaIndex 检索体系,既可作为独立的关键词检索器,也能与其他检索器组合成混合检索。通过阅读 base.py 与 README.md,你可以完整掌握其参数语义、管道结构与节点重建细节,进而在自己的 RAG 应用中直接复用这一能力。

【免费下载链接】llama_indexLlamaIndex is the leading document agent and OCR platform项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询