Skip to main content
本笔记本介绍如何将 MongoDB 向量搜索与 LangChain 结合使用。它还展示了 MongoDB Atlas 嵌入和重排序 API,用于访问 Voyage AI 的最先进嵌入模型和重排序器。
MongoDB Atlas 是一个完全托管的云数据库,可在 AWS、Azure 和 GCP 上使用。它支持原生向量搜索、全文搜索(BM25)以及对 MongoDB 文档数据的混合搜索。
MongoDB 向量搜索 允许将嵌入存储在 MongoDB 文档中,创建向量搜索索引,并使用近似最近邻算法(Hierarchical Navigable Small Worlds)执行 KNN 搜索。它使用 $vectorSearch MQL 阶段
MongoDB Atlas 嵌入和重排序 API 通过 MongoDB Atlas 启用对 Voyage AI 模型的访问。
注意:MongoDBAtlasVectorSearch 接口与社区版中的 MongoDB 向量搜索兼容。

设置

要使用 MongoDB Atlas,您必须首先部署一个集群。要开始使用,请免费注册 Atlas 为了使用 Voyage AI 嵌入和重排序模型,您需要创建一个模型 API 密钥。生成您的 API 密钥,并获取对最新模型的 2 亿免费令牌的访问权限。 首先,安装以下库以遵循本笔记本。
!pip install -qU langchain-mongodb langchain-voyageai langchain-community
将以下代码单元中的占位符值替换为您的 Atlas 集群连接字符串和您的模型 API 密钥。
import os
from pymongo import MongoClient
from langchain_mongodb import MongoDBAtlasVectorSearch
from langchain_mongodb.retrievers import MongoDBAtlasHybridSearchRetriever
from langchain_voyageai import VoyageAIEmbeddings, VoyageAIRerank
from langchain_community.document_loaders import WikipediaLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter

# 设置凭据
MONGODB_ATLAS_URI = "YOUR_ATLAS_CONNECTION_STRING_HERE"
MONGODB_ATLAS_MODEL_API_KEY = "YOUR_ATLAS_MODEL_API_KEY" 
os.environ["VOYAGE_API_KEY"] = MONGODB_ATLAS_MODEL_API_KEY

client = MongoClient(MONGODB_ATLAS_URI)
db_name = "langchain_db"
collection_name = "vector_store_example"
atlas_collection = client[db_name][collection_name]
vector_index_name = "vector_index"

插入数据

我们加载文档,通过 Atlas 托管的 Voyage AI 模型生成嵌入,并以编程方式创建向量搜索索引。
# 加载示例数据
loader = WikipediaLoader(query="MongoDB", load_max_docs=2)
data = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
docs = text_splitter.split_documents(data)

# 初始化嵌入(Atlas 托管的 Voyage AI)
embeddings = VoyageAIEmbeddings(model="voyage-4-lite")

# 初始化向量存储
vector_store = MongoDBAtlasVectorSearch(
    collection=atlas_collection,
    embedding=embeddings,
    index_name=vector_index_name
)

创建向量索引

# 创建向量搜索索引,并为优化的元数据搜索指定特定过滤器
vector_store.create_vector_search_index(
    dimensions=1024,
    wait_until_complete=45 # 等待 45 秒以使索引准备就绪
)
[可选] 除了上面的 vector_store.create_vector_search_index 命令之外,您还可以使用 Atlas UI 创建向量搜索索引,索引定义如下:
{
  "fields":[
    {
      "type": "vector",
      "path": "embedding",
      "numDimensions": 1024,
      "similarity": "cosine"
    }
  ]
}
# 生成文档
vector_store.add_documents(docs)

查询向量存储

语义搜索

根据语义相似性查找最相关的文档。
query = "What is MongoDB Atlas?"
results = vector_store.similarity_search(query, k=3)

for doc in results:
    print(f"* {doc.page_content[:100]}...")

带分数的语义搜索

检索文档及其相关性分数。
results_with_score = vector_store.similarity_search_with_score(query, k=3)

for doc, score in results_with_score:
    print(f"Score: {score:.4f} | Content: {doc.page_content[:80]}...")

带过滤的语义搜索

首先,通过提供要过滤的字段来更新向量搜索索引。
# 创建向量搜索索引,并为优化的元数据搜索指定特定过滤器
vector_store.create_vector_search_index(
    dimensions=1024,
    wait_until_complete=60,
    update=True,
    filters=["source"]
)
使用元数据过滤器缩小结果范围。请注意,Atlas 向量搜索需要显式运算符,如 $eq
# 使用已知存在于我们加载的文档中的来源
sample_source = "https://en.wikipedia.org/wiki/MongoDB"

filtered_results = vector_store.similarity_search(
    query,
    k=3,
    pre_filter={"source": {"$eq": sample_source}}
)

print(f"Retrieved {len(filtered_results)} documents matching source: {sample_source}")

混合搜索

结合向量搜索和全文搜索(关键词),使用互惠排名融合(RRF)。
from langchain_mongodb.index import create_fulltext_search_index

# 使用辅助方法创建搜索索引
create_fulltext_search_index(
   collection = atlas_collection,
    wait_until_complete=60,
   field = "text",
   index_name = "search_index"
)
# 需要在集合上有一个名为 'default' 的标准搜索索引
retriever = MongoDBAtlasHybridSearchRetriever(
    vectorstore=vector_store,
    search_index_name="search_index", 
    fulltext_penalty = 50,
    vector_penalty = 50,
    top_k=5
)

hybrid_docs = retriever.invoke("database-as-a-service")
for doc in hybrid_docs:
   print("Title: " + doc.metadata["title"])
   print("Plot: " + doc.page_content)
   print("Search score: {}".format(doc.metadata["fulltext_score"]))
   print("Vector Search score: {}".format(doc.metadata["vector_score"]))
   print("Total score: {}\n".format(doc.metadata["fulltext_score"] + doc.metadata["vector_score"]))

向量搜索和重排序

两阶段过程:广泛召回后进行高精度重排序,以确保最大相关性。
from langchain_classic.retrievers.contextual_compression import ContextualCompressionRetriever

# 1. 定义基础检索器以获取广泛池
base_retriever = vector_store.as_retriever(search_kwargs={"k": 20})

# 2. 初始化 Atlas 托管的 Voyage AI 重排序器
reranker = VoyageAIRerank(model="rerank-2.5-lite", top_k=3)

# 3. 创建压缩检索器
compression_retriever = ContextualCompressionRetriever(
    base_compressor=reranker, 
    base_retriever=base_retriever
)

print("--- Reranked Results ---")
final_docs = compression_retriever.invoke("Explain how MongoDB stores vectors")
for doc in final_docs:
    print(f"Relevance Score: {doc.metadata['relevance_score']:.4f} | {doc.page_content[:100]}...")

检索增强生成 (RAG)

有关如何将 MongoDB 向量存储集成与 LangChain 结合用于检索增强生成 (RAG) 的指南,请参阅以下教程:

其他说明


API 参考

有关所有 MongoDBAtlasVectorSearch 功能和配置的详细文档,请前往 API 参考