注意
本教程使用 LangChain 的 JavaScript库。有关使用Python库的教程,请参阅 LangChain Python。
您可以将 MongoDB Vector Search 与 LangChain 集成,以构建 LLM 应用程序并实现检索增强生成 (RAG)。本教程演示如何开始使用MongoDB Vector Search 与 LangChain 对数据执行语义搜索并构建 RAG实施。具体来说,您执行以下操作:
设置环境。
在MongoDB中存储自定义数据。
对数据创建MongoDB Vector Search索引。
运行以下向量搜索查询:
语义搜索。
带元数据预过滤的语义搜索。
最大边际相关性 (MMR) Atlas Search 。
使用 MongoDB Vector Search 来回答有关数据的问题,从而实施RAG。
背景
LangChain 是一个开源框架,可通过使用“链”来简化 LLM 应用程序的创建。链是 LangChain 特有的组件,可组合用于各种AI使用案例,包括 RAG。
通过将MongoDB Vector Search 与 LangChain 集成,您可以将MongoDB用作向量数据库,并使用MongoDB Vector Search 从数据中检索语义相似的文档来实现RAG。要学习;了解有关RAG的更多信息,请参阅使用MongoDB进行检索增强生成 (RAG)。
先决条件
如要完成本教程,您必须具备以下条件:
以下MongoDB 集群类型之一:
一个 Atlas 集群,运行 MongoDB 6.0.11、7.0.2 或更高版本。请确保您的 IP 地址包含在 Atlas 项目的访问列表中。
使用Atlas CLI创建的本地Atlas部署。要学习;了解更多信息,请参阅创建本地Atlas部署。
安装了Search 和 Vector Search的MongoDB Community或 Enterprise集群。
Voyage AI API密钥。要创建帐户和API密钥,请参阅 Voyage AI网站。
OpenAI API密钥。您必须拥有一个具有可用于API请求的积分的 OpenAI 帐户。要学习;了解有关注册 OpenAI 帐户的更多信息,请参阅 OpenAI API网站。
用于运行 Node.js 项目的终端和代码编辑器。
设置环境
为此教程设置环境。 要设立环境,请完成以下步骤。
更新您的 package.json 文件。
将您的项目配置为使用 ES 模块 ,方法是将 "type": "module" 添加到 package.json 文件中,然后将其保存。
{ "type": "module", // other fields... }
创建一个名为 get-started.js 的文件并粘贴以下代码。
在项目中,创建一个名为get-started.js的文件,然后将以下代码复制并粘贴到该文件中。 在整个教程中,您将向此文件添加代码。
此初始代码片段导入本教程所需的包,定义环境变量,并建立与MongoDB 集群的连接。
import { formatDocumentsAsString } from "langchain/util/document"; import { MongoClient } from "mongodb"; import { MongoDBAtlasVectorSearch } from "@langchain/mongodb"; import { ChatOpenAI } from "@langchain/openai"; import { VoyageEmbeddings } from "@langchain/community/embeddings/voyage"; import { PDFLoader } from "@langchain/community/document_loaders/fs/pdf"; import { PromptTemplate } from "@langchain/core/prompts"; import { RecursiveCharacterTextSplitter } from "langchain/text_splitter"; import { RunnableSequence, RunnablePassthrough } from "@langchain/core/runnables"; import { StringOutputParser } from "@langchain/core/output_parsers"; import * as fs from 'fs'; process.env.VOYAGEAI_API_KEY = "<api-key>" process.env.OPENAI_API_KEY = "<api-key>"; process.env.MONGODB_URI = "<connection-string>"; const client = new MongoClient(process.env.MONGODB_URI);
替换占位符值。
要完成环境设置,请将 get-started.js 中的 <api-key> 和 <connection-string> 占位符值分别替换为您的 Voyage AI API密钥、OpenAI API密钥和 MongoDB 集群的 SRV 连接字符串。连接字符串应使用以下格式:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
使用MongoDB作为向量存储
在本部分中,您将定义一个异步函数以将自定义数据加载到MongoDB中,并将MongoDB 集群实例化为向量数据库(也称为向量存储)。将以下代码添加到 get-started.js文件中。
注意
在本教程中,您将使用标题为MongoDB Atlas最佳实践的可公开访问的 PDF文档作为向量存储的数据源。本文档介绍了管理MongoDB部署的各种建议和核心概念。
此代码执行以下操作:
通过指定以下参数来配置MongoDB集合:
langchain_db.test作为MongoDB集合来存储文档。vector_index作为用于查询向量存储的索引。text作为包含原始文本内容的字段的名称。embedding作为包含向量嵌入的字段的名称。
通过执行以下操作来准备自定义数据:
从指定 URL 检索原始数据并将其另存为 PDF。
使用文本拆分器将数据分割为较小的文档。
指定数据块参数,它确定每个文档中的字符数以及两个连续文档之间应重叠的字符数。
通过调用
MongoDBAtlasVectorSearch.fromDocuments方法从样本文档创建向量存储。 此方法指定以下参数:要存储在向量数据库中的示例文档。
Voyage AI 的嵌入模型用于将文本转换为
embedding字段的向量嵌入。您的MongoDB 集群配置。
async function run() { try { // Configure your MongoDB collection const database = client.db("langchain_db"); const collection = database.collection("test"); const dbConfig = { collection: collection, indexName: "vector_index", // The name of the MongoDB Search index to use. textKey: "text", // Field name for the raw text content. Defaults to "text". embeddingKey: "embedding", // Field name for the vector embeddings. Defaults to "embedding". }; // Ensure that the collection is empty const count = await collection.countDocuments(); if (count > 0) { await collection.deleteMany({}); } // Save online PDF as a file const rawData = await fetch("https://webassets.mongodb.com/MongoDB_Best_Practices_Guide.pdf"); const pdfBuffer = await rawData.arrayBuffer(); const pdfData = Buffer.from(pdfBuffer); fs.writeFileSync("atlas_best_practices.pdf", pdfData); // Load and split the sample data const loader = new PDFLoader(`atlas_best_practices.pdf`); const data = await loader.load(); const textSplitter = new RecursiveCharacterTextSplitter({ chunkSize: 200, chunkOverlap: 20, }); const docs = await textSplitter.splitDocuments(data); // Instantiate MongoDB as a vector store const embeddingModel = new VoyageEmbeddings({ model: "voyage-3-large" }); const vectorStore = await MongoDBAtlasVectorSearch.fromDocuments(docs, embeddingModel, dbConfig); } finally { // Ensure that the client will close when you finish/error await client.close(); } } run().catch(console.dir);
保存文件,然后运行以下命令将数据加载到MongoDB中。
node get-started.js
提示
运行get-started.js 后,如果您使用的是Atlas ,则可以导航到Atlas用户用户界面中的langchain_db.test 命名空间来验证向量嵌入。
创建MongoDB Vector Search 索引
要在向量存储上启用向量搜索查询,请在 langchain_db.test集合上创建MongoDB Vector Search索引。
将以下代码添加到您在 get-started.js 文件中定义的异步函数中。此代码会创建一个 vectorSearch 类型的索引,而该索引会对以下字段编制索引:
embedding字段作为向量类型。embedding字段包含使用 Voyage AI 的voyage-3-large嵌入模型创建的嵌入。索引定义指定了1024个向量维度,并使用cosine来衡量相似性。loc.pageNumber字段作为筛选器类型,用于按 PDF 中的页码对数据进行预筛选。
此代码还使用等待函数来确保您的搜索索引在使用之前已与数据同步。
1 // Ensure index does not already exist, then create your MongoDB Vector Search index 2 const indexes = await collection.listSearchIndexes("vector_index").toArray(); 3 if(indexes.length === 0){ 4 5 // Define your MongoDB Vector Search Index 6 const index = { 7 name: "vector_index", 8 type: "vectorSearch", 9 definition: { 10 "fields": [ 11 { 12 "type": "vector", 13 "numDimensions": 1024, 14 "path": "embedding", 15 "similarity": "cosine" 16 }, 17 { 18 "type": "filter", 19 "path": "loc.pageNumber" 20 } 21 ] 22 } 23 } 24 25 // Run the helper method 26 const result = await collection.createSearchIndex(index); 27 console.log(result); 28 29 // Wait for index to build and become queryable 30 console.log("Waiting for initial sync..."); 31 await new Promise(resolve => setTimeout(() => { 32 resolve(); 33 }, 10000)); 34 }
保存文件,然后运行以下命令以创建MongoDB Vector Search索引。
node get-started.js
运行向量搜索查询
本部分演示了可以对矢量化数据运行的各种查询。 创建索引后,将以下代码添加到异步函数中,以对数据运行向量Atlas Search查询。
注意
如果您在查询数据时遇到不准确的结果,则索引的同步时间可能比预期长。 增加setTimeout函数中的数字,以便为初始同步留出更多时间。
将以下代码添加到异步函数中并保存文件。
以下代码使用 similaritySearch 方法对字符串 MongoDB Atlas security执行基本语义搜索。它返回按相关性排名的文档列表,其中仅包含 pageContent 和 pageNumber 字段。
// Basic semantic search const basicOutput = await vectorStore.similaritySearch("MongoDB Atlas security"); const basicResults = basicOutput.map((results => ({ pageContent: results.pageContent, pageNumber: results.metadata.loc.pageNumber, }))) console.log("Semantic Search Results:") console.log(basicResults)
运行以下命令以执行查询。
node get-started.js
Semantic Search Results: [ { pageContent: 'Atlas free tier, or download MongoDB for local \n' + 'development.\n' + 'Review the MongoDB manuals and tutorials in our \n' + 'documentation. \n' + 'More Resources\n' + 'For more on getting started in MongoDB:', pageNumber: 30 }, { pageContent: 'read isolation. \n' + 'With MongoDB Atlas, you can achieve workload isolation with dedicated analytics nodes. Visualization \n' + 'tools like Atlas Charts can be configured to read from analytics nodes only.', pageNumber: 21 }, { pageContent: '• Zoned Sharding — You can define specific rules governing data placement in a sharded cluster.\n' + 'Global Clusters in MongoDB Atlas allows you to quickly implement zoned sharding using a visual UI or', pageNumber: 27 }, { pageContent: 'are updated, associated indexes must be maintained, incurring additional CPU and disk I/O overhead. \n' + 'If you\'re running fully managed databases on MongoDB Atlas, the built-in Performance Advisor', pageNumber: 20 } ]
您可以使用 MQL 匹配表达式来预过滤您的数据,该表达式将索引字段与集合中的另一个值进行比较。您必须将要过滤的任何元数据字段作为 filter 类型进行索引。要了解详情,请参阅如何为向量搜索建立字段索引。
注意
在为本教程创建索引时,您已指定loc.pageNumber字段作为筛选器。
将以下代码添加到异步函数中并保存文件。
以下代码使用 similaritySearch 方法对字符串 MongoDB Atlas security 执行语义搜索。它指定以下参数:
以
3形式返回的文件数。针对
loc.pageNumber字段的预筛选器,使用$eq操作符仅匹配出现在17页上的文档。
它返回按相关性排名的文档列表,仅包含 pageContent 和 pageNumber 字段。
// Semantic search with metadata filter const filteredOutput = await vectorStore.similaritySearch("MongoDB Atlas Search", 3, { preFilter: { "loc.pageNumber": {"$eq": 22 }, } }); const filteredResults = filteredOutput.map((results => ({ pageContent: results.pageContent, pageNumber: results.metadata.loc.pageNumber, }))) console.log("Semantic Search with Filtering Results:") console.log(filteredResults)
运行以下命令以执行查询。
node get-started.js
Semantic Search with Filtering Results: [ { pageContent: 'Atlas Search is built for the MongoDB document data model and provides higher performance and', pageNumber: 22 }, { pageContent: 'Figure 9: Atlas Search queries are expressed through the MongoDB Query API and backed by the leading search engine library, \n' + 'Apache Lucene.', pageNumber: 22 }, { pageContent: 'consider using Atlas Search. The service is built on fully managed Apache Lucene but exposed to users \n' + 'through the MongoDB Aggregation Framework.', pageNumber: 22 } ]
您还可以根据最大边际相关性 (MMR) 执行语义搜索,MMR 是一种针对多样性进行优化的语义相关性度量。
将以下代码添加到异步函数中并保存文件。
以下代码使用 maxMarginalRelevanceSearch 方法搜索字符串 MongoDB Atlas security。它还指定了一个定义以下可选参数的对象:
k限制返回文档的数量为3。fetchK将文档传递给 MMR 算法之前仅获取10个文档。
它返回按相关性排名的文档列表,仅包含 pageContent 和 pageNumber 字段。
// Max Marginal Relevance search const mmrOutput = await vectorStore.maxMarginalRelevanceSearch("MongoDB Atlas security", { k: 3, fetchK: 10, }); const mmrResults = mmrOutput.map((results => ({ pageContent: results.pageContent, pageNumber: results.metadata.loc.pageNumber, }))) console.log("Max Marginal Relevance Search Results:") console.log(mmrResults)
运行以下命令以执行查询。
node get-started.js
Max Marginal Relevance Search Results: [ { pageContent: 'Atlas Search is built for the MongoDB document data model and provides higher performance and', pageNumber: 22 }, { pageContent: '• Zoned Sharding — You can define specific rules governing data placement in a sharded cluster.\n' + 'Global Clusters in MongoDB Atlas allows you to quickly implement zoned sharding using a visual UI or', pageNumber: 27 }, { pageContent: 'read isolation. \n' + 'With MongoDB Atlas, you can achieve workload isolation with dedicated analytics nodes. Visualization \n' + 'tools like Atlas Charts can be configured to read from analytics nodes only.', pageNumber: 21 } ]
提示
有关更多信息,请参阅API参考文档。
回答有关数据的问题
本部分演示使用MongoDB Vector Search 和 LangChain 的两种不同 RAG 实施。现在您已经使用MongoDB Vector Search检索语义相似的文档,使用以下代码示例提示法学硕士回答针对MongoDB Vector Search 返回的文档的问题。
将以下代码添加到异步函数中并保存文件。
此代码执行以下操作:
将 MongoDB Vector Search 实例化为检索器,以查询语义相似的文档。
定义 LangChain 提示模板,指示 LLM 使用这些文档作为查询的上下文。LangChain 将这些文档传递给
{context}输入变量,并将您的查询传递给{question}变量。构建一个链,其使用 OpenAI 的聊天模型,根据您的提示生成上下文感知的回复。
用有关 Atlas 安全建议的示例查询提示链。
返回 LLM 的响应和用作上下文的文档。
// Implement RAG to answer questions on your data const retriever = vectorStore.asRetriever(); const prompt = PromptTemplate.fromTemplate(`Answer the question based on the following context: {context} Question: {question}`); const model = new ChatOpenAI({}); const chain = RunnableSequence.from([ { context: retriever.pipe(formatDocumentsAsString), question: new RunnablePassthrough(), }, prompt, model, new StringOutputParser(), ]); // Prompt the LLM const question = "How can I secure my MongoDB Atlas cluster?"; const answer = await chain.invoke(question); console.log("Question: " + question); console.log("Answer: " + answer); // Return source documents const retrievedResults = await retriever.getRelevantDocuments(question) const documents = retrievedResults.map((documents => ({ pageContent: documents.pageContent, pageNumber: documents.metadata.loc.pageNumber, }))) console.log("\nSource documents:\n" + JSON.stringify(documents, 1, 2))
运行以下命令以执行您的文件。
保存文件后,运行以下命令。 生成的响应可能会有所不同。
node get-started.js
Question: How can I secure my MongoDB Atlas cluster? Answer: The given context does not explicitly provide detailed steps to secure a MongoDB Atlas cluster. However, based on general best practices, here are some common steps to secure your MongoDB Atlas cluster: 1. **Enable Network Access Controls**: Configure IP whitelists to only allow connections from trusted IP addresses. 2. **Use Strong Authentication and Authorization**: Enable SCRAM (Salted Challenge Response Authentication Mechanism) for authenticating users and define roles with specific permissions. 3. **Encrypt Data**: Ensure data is encrypted both at rest and in transit by default in MongoDB Atlas. 4. **Enable VPC Peering (if applicable)**: Use Virtual Private Cloud (VPC) peering for secure and private connections. 5. **Monitor Activity**: Use MongoDB Atlas's built-in monitoring to track cluster activity and detect unauthorized attempts or anomalies. 6. **Implement Automated Backups**: Secure backups and ensure they are protected from unauthorized access. 7. **Educate Yourself**: Continuously refer to the MongoDB documentation and follow security best practices. It is recommended to visit the MongoDB documentation and security guides for the most accurate and detailed steps tailored to your specific use case. Source documents: [ { "pageContent": "Atlas free tier, or download MongoDB for local \ndevelopment.\nReview the MongoDB manuals and tutorials in our \ndocumentation. \nMore Resources\nFor more on getting started in MongoDB:", "pageNumber": 30 }, { "pageContent": "read isolation. \nWith MongoDB Atlas, you can achieve workload isolation with dedicated analytics nodes. Visualization \ntools like Atlas Charts can be configured to read from analytics nodes only.", "pageNumber": 21 }, { "pageContent": "• Zoned Sharding — You can define specific rules governing data placement in a sharded cluster.\nGlobal Clusters in MongoDB Atlas allows you to quickly implement zoned sharding using a visual UI or", "pageNumber": 27 }, { "pageContent": "22\nWorkload Type: Search\nIf your application requires rich full-text search functionality and you are running MongoDB on Atlas,", "pageNumber": 22 } ]
将以下代码添加到异步函数中并保存文件。
此代码执行以下操作:
将 MongoDB Vector Search 实例化为检索器,以查询语义相似的文档。它还指定了以下可选参数:
searchType为mmr,指定MongoDB Vector Search 根据最大边际相关性 (MMR) 检索文档。filter在log.pageNumbers字段上添加预过滤器,仅包含出现在 17 页上的文档。以下特定于 MMR 的参数:
fetchK将文档传递给 MMR 算法之前仅获取20个文档。lambda,该值介于0和1之间,用于确定结果的多样性程度,0代表最大多样性,1代表最小多样性。
定义 LangChain 提示模板,指示 LLM 使用这些文档作为查询的上下文。LangChain 将这些文档传递给
{context}输入变量,并将您的查询传递给{question}变量。构建一个链,其使用 OpenAI 的聊天模型,根据您的提示生成上下文感知的回复。
用有关 Atlas 安全建议的示例查询提示链。
返回 LLM 的响应和用作上下文的文档。
// Implement RAG to answer questions on your data const retriever = await vectorStore.asRetriever({ searchType: "mmr", // Defaults to "similarity filter: { preFilter: { "loc.pageNumber": { "$eq": 17 } } }, searchKwargs: { fetchK: 20, lambda: 0.1, }, }); const prompt = PromptTemplate.fromTemplate(`Answer the question based on the following context: {context} Question: {question}`); const model = new ChatOpenAI({}); const chain = RunnableSequence.from([ { context: retriever.pipe(formatDocumentsAsString), question: new RunnablePassthrough(), }, prompt, model, new StringOutputParser(), ]); // Prompt the LLM const question = "How can I secure my MongoDB Atlas cluster?"; const answer = await chain.invoke(question); console.log("Question: " + question); console.log("Answer: " + answer); // Return source documents const retrievedResults = await retriever.getRelevantDocuments(question) const documents = retrievedResults.map((documents => ({ pageContent: documents.pageContent, pageNumber: documents.metadata.loc.pageNumber, }))) console.log("\nSource documents:\n" + JSON.stringify(documents, 1, 2))
运行以下命令以执行您的文件。
保存文件后,运行以下命令。 生成的响应可能会有所不同。
node get-started.js
Question: How can I secure my MongoDB Atlas cluster? Answer: To secure your MongoDB Atlas cluster, you can implement the following best practices: 1. **Enable Authentication and Authorization** Ensure that authentication is enabled, which is the default for MongoDB Atlas. Use role-based access control (RBAC) to grant users only the permissions they need. 2. **Use Strong Passwords or Authentication Mechanisms** Avoid simple passwords. Use strong, complex passwords for all database users. Alternatively, use certificate-based authentication or federated authentication with your identity provider. 3. **Whitelist IP Addresses** Configure your Access List (IP Whitelist) to restrict access to trusted IP addresses. This ensures that only specified IP addresses can connect to your cluster. 4. **Enable Network Encryption (TLS/SSL)** MongoDB Atlas supports TLS/SSL by default for securing data in transit. Ensure applications are configured to connect with SSL/TLS-enabled settings. 5. **Use End-to-End Encryption (Client-Side Field-Level Encryption)** Implement client-side field-level encryption to ensure sensitive fields are encrypted end-to-end. 6. **Regularly Rotate Authentication Credentials** Periodically rotate users' passwords or access keys to mitigate the risks of credential exposure. 7. **Use Private Networking** If supported, use Virtual Private Cloud (VPC) peering or private endpoints, such as AWS PrivateLink, to connect securely to your MongoDB Atlas cluster without using the public internet. 8. **Enable Database Auditing** Enable auditing to track database activity and detect potential anomalies or unauthorized access. 9. **Enable Backup and Data Recovery** Regularly back up your data using MongoDB Atlas' automated backup systems to ensure business continuity in case of accidental deletions or data loss. 10. **Keep the MongoDB Drivers Updated** Use the latest version of MongoDB drivers in your application to benefit from security updates and enhancements. 11. **Monitor and Set Alerts** Use MongoDB Atlas' monitoring tools to track metrics and set up alerts for suspicious activities or unusual resource consumption. 12. **Implement Application-Level Security** Ensure your application properly handles user authentication, session management, and input sanitization to prevent unauthorized access or injection attacks. 13. **Watch for Security Best Practices Updates** Regularly review MongoDB Atlas documentation and security advisories to stay aware of new features and recommendations. By following these practices, you can greatly enhance the security posture of your MongoDB Atlas cluster. Source documents: [ { "pageContent": "Optimizing Data \nAccess Patterns\nNative tools in MongoDB for improving query \nperformance and reducing overhead.", "pageNumber": 17 } ]
后续步骤
要学习;了解如何将MongoDB Vector Search 与 LangGraph 集成,请参阅将MongoDB与 LangGraph.js 集成。
MongoDB 还提供以下开发者资源: