跳至主要內容

在向量資料庫中儲存嵌入向量

產生嵌入向量後,必須將其儲存在支援向量相似度搜尋的資料庫中。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 官方文件

搭配 MongoDB 使用 VoyageAI

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 維(或自訂)
警告

索引建立後便無法變更維度。若要使用不同模型,請刪除索引,並以新的維度大小重新建立。

資料庫命名規則
「資料庫命名規則」的直接連結

各向量資料庫都會對索引與 collection 強制執行特定命名慣例,以確保相容性並避免衝突。

Collection(索引)名稱必須:

  • 以字母或底線開頭
  • 長度不得超過 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,就只會剩下數值嵌入向量,無法傳回原始文字或篩選結果。請務必至少將來源文字儲存為 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)