DuckDB Vector 存储
DuckDB storage 实现使用进程内分析数据库 DuckDB 提供嵌入式高性能 Vector 搜索解决方案。它使用 VSS extension,通过 HNSW 索引进行 Vector 相似度搜索,提供轻量、高效且无需外部服务器的 Vector 数据库。
它是 @mastra/duckdb 包的一部分,提供高效的 Vector 相似度搜索和元数据过滤。
安装安装的直接链接
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/duckdb@latest
pnpm add @mastra/duckdb@latest
yarn add @mastra/duckdb@latest
bun add @mastra/duckdb@latest
用法用法的直接链接
import { DuckDBVector } from "@mastra/duckdb";
// Create a new vector store instance
const store = new DuckDBVector({
id: "duckdb-vector",
path: ":memory:", // or './vectors.duckdb' for file persistence
});
// Create an index
await store.createIndex({
indexName: "myCollection",
dimension: 1536,
metric: "cosine",
});
// Add vectors with metadata
const vectors = [[0.1, 0.2, ...], [0.3, 0.4, ...]];
const metadata = [
{ text: "first document", category: "A" },
{ text: "second document", category: "B" },
];
await store.upsert({
indexName: "myCollection",
vectors,
metadata,
});
// Query similar vectors
const queryVector = [0.1, 0.2, ...];
const results = await store.query({
indexName: "myCollection",
queryVector,
topK: 10,
filter: { category: "A" },
});
// Clean up
await store.close();
构造函数选项构造函数选项的直接链接
id:
string
Vector 存储实例的唯一标识符
path?:
string
= ':memory:'
数据库文件路径。使用 ':memory:' 创建内存数据库,或使用 './vectors.duckdb' 等文件路径实现持久化。
dimensions?:
number
= 1536
Vector embedding 的默认维度
metric?:
'cosine' | 'euclidean' | 'dotproduct'
= cosine
相似度搜索的默认距离度量
方法方法的直接链接
createIndex()createindex的直接链接
创建新的 Vector collection,并可选择添加 HNSW 索引以进行快速近似最近邻搜索。
indexName:
string
要创建的索引名称
dimension:
number
Vector 维度大小(必须与 embedding 模型匹配)
metric?:
'cosine' | 'euclidean' | 'dotproduct'
= cosine
相似度搜索的距离度量
upsert()upsert的直接链接
在索引中添加或更新 Vector 及其元数据。
indexName:
string
要插入数据的索引名称
vectors:
number[][]
embedding Vector 数组
metadata?:
Record<string, any>[]
每个 Vector 的元数据
ids?:
string[]
可选的 Vector ID(未提供时自动生成 UUID)
query()query的直接链接
搜索相似 Vector,并可选择使用元数据过滤。
indexName:
string
要在其中搜索的索引名称
queryVector:
number[]
用于查找相似 Vector 的查询 Vector
topK?:
number
= 10
要返回的结果数量
filter?:
Filter
使用类似 MongoDB 查询语法的元数据过滤条件
includeVector?:
boolean
= false
是否在结果中包含 Vector 数据
describeIndex()describeindex的直接链接
获取索引相关信息。
indexName:
string
要描述的索引名称
返回:
interface IndexStats {
dimension: number
count: number
metric: 'cosine' | 'euclidean' | 'dotproduct'
}
deleteIndex()deleteindex的直接链接
删除索引及其所有数据。
indexName:
string
要删除的索引名称
listIndexes()listindexes的直接链接
列出数据库中的所有 Vector 索引。
返回:Promise<string[]>
updateVector()updatevector的直接链接
通过 ID 或元数据过滤条件更新单个 Vector。必须提供 id 或 filter,但不能同时提供二者。
indexName:
string
包含该 Vector 的索引名称
id?:
string
要更新的 Vector 条目 ID(与 filter 互斥)
filter?:
Record<string, any>
用于识别要更新 Vector 的元数据过滤条件(与 id 互斥)
update:
object
包含 Vector 和/或元数据的更新数据
update.vector?:
number[]
要更新的新 Vector 数据
update.metadata?:
Record<string, any>
要更新的新元数据
deleteVector()deletevector的直接链接
根据 ID 从索引中删除特定 Vector 条目。
indexName:
string
包含该 Vector 的索引名称
id:
string
要删除的 Vector 条目 ID
deleteVectors()deletevectors的直接链接
通过 ID 或元数据过滤条件删除多个 Vector。必须提供 ids 或 filter,但不能同时提供二者。
indexName:
string
包含要删除 Vector 的索引名称
ids?:
string[]
要删除的 Vector ID 数组(与 filter 互斥)
filter?:
Record<string, any>
用于识别要删除 Vector 的元数据过滤条件(与 ids 互斥)
close()close的直接链接
关闭数据库连接并释放资源。
await store.close()
响应类型响应类型的直接链接
查询结果按以下格式返回:
interface QueryResult {
id: string
score: number
metadata: Record<string, any>
vector?: number[] // Only included if includeVector is true
}
过滤运算符过滤运算符的直接链接
DuckDB Vector 存储支持类似 MongoDB 的过滤运算符:
| 类别 | 运算符 |
|---|---|
| 比较 | $eq, $ne, $gt, $gte, $lt, $lte |
| 逻辑 | $and, $or, $not, $nor |
| 数组 | $in, $nin |
| 元素 | $exists |
| 文本 | $contains |
过滤示例过滤示例的直接链接
// Allegato operators
const results = await store.query({
indexName: "docs",
queryVector: [...],
filter: {
$and: [
{ category: "electronics" },
{ price: { $gte: 100, $lte: 500 } },
],
},
});
// Nested field access
const results = await store.query({
indexName: "docs",
queryVector: [...],
filter: { "user.profile.tier": "premium" },
});
距离度量距离度量的直接链接
| 度量 | 描述 | 分数含义 | 最适合 |
|---|---|---|---|
cosine | 余弦相似度 | 0-1(1 = 最相似) | 文本 embedding、归一化 Vector |
euclidean | L2 距离 | 0-∞(0 = 最相似) | 图像 embedding、空间数据 |
dotproduct | 内积 | 越高越相似 | Vector 大小会影响结果的场景 |
错误处理错误处理的直接链接
针对不同的失败情况,该存储会抛出特定错误:
try {
await store.query({
indexName: 'my-collection',
queryVector: queryVector,
})
} catch (error) {
if (error.message.includes('not found')) {
console.error('The specified index does not exist')
} else if (error.message.includes('Invalid identifier')) {
console.error('Index name contains invalid characters')
} else {
console.error('Vector store error:', error.message)
}
}
常见错误情况包括:
- 索引名称格式无效
- 找不到索引/表
- 查询 Vector 与索引的维度不匹配
- 删除/更新操作中的 filter 或 ids 数组为空
- 违反互斥约束(同时提供
id和filter)
使用场景使用场景的直接链接
嵌入式语义搜索嵌入式语义搜索的直接链接
构建支持离线运行的 AI 应用,完全在进程内执行语义搜索:
const store = new DuckDBVector({
id: 'offline-search',
path: './search.duckdb',
})
本地 RAG pipeline本地 RAG pipeline的直接链接
在本地处理敏感文档,无需将数据发送到云端 Vector 数据库:
const store = new DuckDBVector({
id: 'private-rag',
path: './confidential.duckdb',
dimensions: 1536,
})
开发和测试开发和测试的直接链接
无需任何基础设施即可快速构建 Vector 搜索功能原型:
const store = new DuckDBVector({
id: 'dev-store',
path: ':memory:', // Fast in-memory for tests
})