跳到主要内容

在向量数据库中存储嵌入

生成嵌入后,需要将其存储到支持向量相似度搜索的数据库中。Mastra 为在不同向量数据库中存储和查询嵌入提供一致的接口。

支持的数据库
支持的数据库的直接链接

vector-store.ts
import { MongoDBVector } from '@mastra/mongodb'

const store = new MongoDBVector({
id: 'mongodb-vector',
uri: process.env.MONGODB_URI,
dbName: process.env.MONGODB_DB_NAME,
})
await store.createIndex({
indexName: 'myCollection',
dimension: 1536,
})
await store.upsert({
indexName: 'myCollection',
vectors: embeddings,
metadata: chunks.map(chunk => ({ text: chunk.text })),
})

使用 MongoDB Atlas Vector Search

有关详细设置说明和最佳实践,请参阅 MongoDB Atlas Vector Search 官方文档

将 VoyageAI 与 MongoDB 配合使用

MongoDB 可与针对检索任务优化的 VoyageAI 嵌入模型无缝配合使用。完整示例和专用模型请参阅 VoyageAI 嵌入文档MongoDB 向量参考

混合搜索(向量 + 全文)

MongoDB 支持使用服务器端 $rankFusion 融合向量相似度和 BM25 全文搜索的混合搜索(需要 MongoDB >= 8.0;从 8.1 起正式可用,并已在 Atlas 8.0.x 上启用)。需要结合语义检索和基于关键词的检索时,此功能很有用:

await store.createSearchIndex({ indexName: 'myCollection', fields: ['text'] })
const results = await store.hybridQuery({
indexName: 'myCollection',
queryVector: embedding,
query: 'search terms',
paths: ['text'],
topK: 10,
})

有关 createSearchIndex()textQuery()hybridQuery() 的详细信息,请参阅 MongoDB 向量参考

使用向量存储
使用向量存储的直接链接

初始化后,所有向量存储都使用同一个接口来创建索引、upsert 嵌入和执行查询。

创建索引
创建索引的直接链接

存储嵌入之前,需要创建一个维度大小与嵌入模型相匹配的索引:

store-embeddings.ts
// Create an index with dimension 1536 (for text-embedding-3-small)
await store.createIndex({
indexName: 'myCollection',
dimension: 1536,
})

维度大小必须与所选嵌入模型的输出维度一致。常见维度大小如下:

  • OpenAI text-embedding-3-small:1536 维(也可以自定义,例如 256)
  • Cohere embed-multilingual-v3:1024 维
  • VoyageAI voyage-3.5:1024 维(也可以自定义为 256、512、1024、2048)
  • Google gemini-embedding-001:768 维(也可以自定义)
注意

索引创建后无法更改维度。要使用不同模型,请删除索引,并使用新的维度大小重新创建。

数据库命名规则
数据库命名规则的直接链接

每个向量数据库都会对索引和集合实施特定命名约定,以确保兼容性并防止冲突。

集合(索引)名称必须:

  • 以字母或下划线开头
  • 长度不超过 120 字节
  • 只能包含字母、数字、下划线或点
  • 不能包含 $ 或空字符
  • 示例:my_collection.123 有效
  • 示例:my-index 无效(包含连字符)
  • 示例:My$Collection 无效(包含 $

Upsert 嵌入
Upsert 嵌入的直接链接

创建索引后,可以将嵌入及其基本 metadata 一起存储:

store-embeddings.ts
// Store embeddings with their corresponding metadata
await store.upsert({
indexName: 'myCollection', // index name
vectors: embeddings, // array of embedding vectors
metadata: chunks.map(chunk => ({
text: chunk.text, // The original text content
id: chunk.id, // Optional unique identifier
})),
})

Upsert 操作:

  • 接受嵌入向量数组及其对应的 metadata
  • 如果现有向量具有相同 ID,则更新这些向量
  • 如果向量不存在,则创建新向量
  • 自动对大型数据集执行批处理

添加 metadata
添加 metadata的直接链接

向量存储支持丰富的 metadata(任何可序列化为 JSON 的字段),用于过滤和组织。由于 metadata 不使用固定 schema 存储,请采用一致的字段命名,避免出现意外查询结果。

注意

Metadata 对向量存储非常重要。如果没有它,就只有数值嵌入,无法返回原始文本或过滤结果。请始终至少将源文本存储为 metadata。

// Store embeddings with rich metadata for better organization and filtering
await store.upsert({
indexName: 'myCollection',
vectors: embeddings,
metadata: chunks.map(chunk => ({
// Basic content
text: chunk.text,
id: chunk.id,

// Document organization
source: chunk.source,
category: chunk.category,

// Temporal metadata
createdAt: new Date().toISOString(),
version: '1.0',

// Custom fields
language: chunk.language,
author: chunk.author,
confidenceScore: chunk.score,
})),
})

Metadata 的主要注意事项:

  • 严格规范字段命名,'category' 与 'Category' 等不一致会影响查询
  • 仅包含计划用于过滤或排序的字段,额外字段会增加开销
  • 添加时间戳(例如 'createdAt'、'lastUpdated')以跟踪内容新鲜度

删除向量
删除向量的直接链接

构建 RAG 应用时,经常需要在文档删除或更新后清理陈旧向量。Mastra 提供 deleteVectors 方法,支持按 metadata 过滤器删除向量,从而轻松移除与特定文档关联的所有嵌入。

按 Metadata 过滤器删除
按 Metadata 过滤器删除的直接链接

最常见的用例是在用户删除特定文档时,删除该文档的所有向量:

delete-vectors.ts
// Delete all vectors for a specific document
await store.deleteVectors({
indexName: 'myCollection',
filter: { docId: 'document-123' },
})

这在以下情况下尤其有用:

  • 用户删除文档,需要移除其所有数据块
  • 正在为文档重新建立索引,并希望先移除旧向量
  • 需要清理特定用户或租户的向量

删除多个文档
删除多个文档的直接链接

还可以使用复杂过滤器,删除匹配多个条件的向量:

delete-vectors-advanced.ts
// Delete all vectors for multiple documents
await store.deleteVectors({
indexName: 'myCollection',
filter: {
docId: { $in: ['doc-1', 'doc-2', 'doc-3'] },
},
})

// Delete vectors for a specific user's documents
await store.deleteVectors({
indexName: 'myCollection',
filter: {
$and: [{ userId: 'user-123' }, { status: 'archived' }],
},
})

按向量 ID 删除
按向量 ID 删除的直接链接

如果要删除特定向量 ID,可以直接传入:

delete-by-ids.ts
// Delete specific vectors by their IDs
await store.deleteVectors({
indexName: 'myCollection',
ids: ['vec-1', 'vec-2', 'vec-3'],
})

最佳实践
最佳实践的直接链接

  • 在批量插入前创建索引
  • 对大量插入使用批处理操作(upsert 方法会自动处理批次)
  • 仅存储查询时会用到的 metadata
  • 使嵌入维度与模型匹配(例如 text-embedding-3-small 为 1536)