> Discover all available pages from the documentation index: https://mastra.zisheng.pro/llms.txt # Amazon S3 Vector 存储 `S3Vectors` 类使用 [Amazon S3 Vectors(预览版)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-vectors.html)提供 Vector 搜索。它将 Vector 存储在 **Vector bucket** 中,并在 **Vector index** 中执行相似度搜索,同时支持基于 JSON 的元数据过滤器。 > **注意:** Amazon S3 Vectors 是一项预览版服务。预览功能可能随时变更或移除,恕不另行通知,并且不受 AWS SLA 保障。其行为、限制和区域可用性都可能随时变化。为了与 AWS 保持一致,此库可能会引入破坏性变更。 ## 安装 **npm**: ```bash npm install @mastra/s3vectors@latest ``` **pnpm**: ```bash pnpm add @mastra/s3vectors@latest ``` **Yarn**: ```bash yarn add @mastra/s3vectors@latest ``` **Bun**: ```bash bun add @mastra/s3vectors@latest ``` ## 用法示例 ```typescript import { S3Vectors } from '@mastra/s3vectors' const store = new S3Vectors({ vectorBucketName: process.env.S3_VECTORS_BUCKET_NAME!, // e.g. "my-vector-bucket" clientConfig: { region: process.env.AWS_REGION!, // credentials use the default AWS provider chain }, // Optional: mark large/long-text fields as non-filterable at index creation time nonFilterableMetadataKeys: ['content'], }) // Create an index (names are normalized: "_" → "-" and lowercased) await store.createIndex({ indexName: 'my_index', dimension: 1536, metric: 'cosine', // "euclidean" also supported; "dotproduct" is NOT supported }) // Upsert vectors (ids auto-generated if omitted). Date values in metadata are serialized to epoch ms. const ids = await store.upsert({ indexName: 'my_index', vectors: [ [0.1, 0.2 /* … */], [0.3, 0.4 /* … */], ], metadata: [ { text: 'doc1', genre: 'documentary', year: 2023, createdAt: new Date('2024-01-01'), }, { text: 'doc2', genre: 'comedy', year: 2021 }, ], }) // Query with metadata filters (implicit AND is canonicalized) const results = await store.query({ indexName: 'my-index', queryVector: [0.1, 0.2 /* … */], topK: 10, // Service-side limits may apply (commonly 30) filter: { genre: { $in: ['documentary', 'comedy'] }, year: { $gte: 2020 } }, includeVector: false, // set true to include raw vectors (may trigger a secondary fetch) }) // Clean up resources (closes the underlying HTTP handler) await store.disconnect() ``` ## 构造函数选项 **vectorBucketName** (`string`): 目标 S3 Vectors Vector bucket 的名称。 **clientConfig** (`S3VectorsClientConfig`): AWS SDK v3 客户端选项(例如 region、credentials)。 **nonFilterableMetadataKeys** (`string[]`): 不应支持过滤的元数据键(创建索引时应用)。适用于 content 等大型文本字段。 ## 方法 ### `createIndex()` 在配置的 Vector bucket 中创建新的 Vector index。如果该索引已经存在,此调用会验证 schema 并且不执行任何操作(保留现有度量和维度)。 **indexName** (`string`): 逻辑索引名称。会在内部进行规范化:下划线替换为连字符,并将名称转换为小写。 **dimension** (`number`): Vector 维度(必须与你的嵌入模型匹配) **metric** (`'cosine' | 'euclidean'`): 用于相似度搜索的距离度量。S3 Vectors 不支持 dotproduct。 (Default: `cosine`) ### `upsert()` 添加或替换 Vector(写入完整记录)。如果未提供 `ids`,则会生成 UUID。 **indexName** (`string`): 要向其中执行 upsert 的索引名称 **vectors** (`number[][]`): 嵌入 Vector 数组 **metadata** (`Record[]`): 每个 Vector 的元数据 **ids** (`string[]`): 可选的 Vector ID(未提供时自动生成) ### `query()` 搜索最近邻,并可选择应用元数据过滤。 **indexName** (`string`): 要查询的索引名称 **queryVector** (`number[]`): 用于查找相似 Vector 的查询 Vector **topK** (`number`): 要返回的结果数量 (Default: `10`) **filter** (`S3VectorsFilter`): 基于 JSON 的元数据过滤器,支持 $and、$or、$eq、$ne、$gt、$gte、$lt、$lte、$in、$nin、$exists。 **includeVector** (`boolean`): 是否在结果中包含 Vector (Default: `false`) > **备注:** 结果中包含 `score = 1/(1 + distance)`,因此分数越高越好,同时保留底层的距离排序。 ### `describeIndex()` 返回索引的相关信息。 **indexName** (`string`): 要描述的索引名称。 返回: ```typescript interface IndexStats { dimension: number count: number // computed via ListVectors pagination (O(n)) metric: 'cosine' | 'euclidean' } ``` ### `deleteIndex()` 删除索引及其数据。 **indexName** (`string`): 要删除的索引。 ### `listIndexes()` 列出已配置 Vector bucket 中的所有索引。 返回:`Promise` ### `updateVector()` 更新索引中特定 ID 对应的 Vector 或元数据。 **indexName** (`string`): 包含该 Vector 的索引。 **id** (`string`): 要更新的 ID。 **update** (`object`): 包含 Vector 和/或元数据的更新数据 **update.vector** (`number[]`): 要更新的新 Vector 数据 **update.metadata** (`Record`): 要更新的新元数据 ### `deleteVector()` 按 ID 删除特定 Vector。 **indexName** (`string`): 包含该 Vector 的索引。 **id** (`string`): 要删除的 ID。 ### `disconnect()` 关闭底层 AWS SDK HTTP handler,以释放 socket。 ## 响应类型 查询结果以以下格式返回: ```typescript interface QueryResult { id: string score: number // 1/(1 + distance) metadata: Record vector?: number[] // Only included if includeVector is true } ``` ## 过滤器语法 S3 Vectors 仅支持一组严格限定的运算符和值类型。Mastra 过滤器转换器会: - **将隐式 AND 规范化**:`{a:1,b:2}` → `{ $and: [{a:1},{b:2}] }`。 - **将 Date 值规范化**为 epoch 毫秒数,以用于数值比较和数组元素。 - **禁止在相等比较中使用 Date**(`field: value` 或 `$eq/$ne`)。相等比较值必须是 **string | number | boolean**。 - **拒绝**将 null/undefined 用于相等比较。**不支持数组相等比较**(请使用 `$in`/`$nin`)。 - 顶层逻辑运算符只允许使用 **`$and` / `$or`**。 - 逻辑运算符必须包含**字段条件**(不能直接包含运算符)。 **支持的运算符:** - **逻辑:** `$and`、`$or`(非空数组) - **基本:** `$eq`、`$ne`(string | number | boolean) - **数值:** `$gt`、`$gte`、`$lt`、`$lte`(number 或 `Date` → epoch 毫秒数) - **数组:** `$in`、`$nin`(由 string | number | boolean 构成的非空数组;`Date` → epoch 毫秒数) - **元素:** `$exists`(boolean) **不支持/不允许(会被拒绝):** `$not`、`$nor`、`$regex`、`$all`、`$elemMatch`、`$size`、`$text` 等。 **示例:** ```typescript // Implicit AND { genre: { $in: ["documentary", "comedy"] }, year: { $gte: 2020 } } // Explicit logicals and ranges { $and: [ { price: { $gte: 100, $lte: 1000 } }, { $or: [{ stock: { $gt: 0 } }, { preorder: true }] } ] } // Dates in range (converted to epoch ms) { timestamp: { $gt: new Date("2024-01-01T00:00:00Z") } } ``` > **备注:** 如果在创建索引时设置了 `nonFilterableMetadataKeys`,这些键仍会存储,但**不能**用于过滤器。 ## 错误处理 该存储会抛出可捕获的类型化错误: ```typescript try { await store.query({ indexName: 'index-name', queryVector: queryVector, }) } catch (error) { if (error instanceof VectorStoreError) { console.log(error.code) // 'connection_failed' | 'invalid_dimension' | etc console.log(error.details) // Additional error context } } ``` ## 环境变量 连接应用时通常使用以下环境变量: - `S3_VECTORS_BUCKET_NAME`:你的 S3 **Vector bucket** 名称(用于填充 `vectorBucketName`)。 - `AWS_REGION`:S3 Vectors bucket 所在的 AWS 区域。 - **AWS 凭证**:通过标准 AWS SDK Provider chain 提供(`AWS_ACCESS_KEY_ID`、`AWS_SECRET_ACCESS_KEY`、`AWS_PROFILE` 等)。 ## 最佳实践 - 选择与你的嵌入模型匹配的度量(`cosine` 或 `euclidean`)。不支持 `dotproduct`。 - 保持**可过滤**元数据小巧且结构化(string/number/boolean)。将大型文本(例如 `content`)存储为**不可过滤**数据。 - 对嵌套元数据使用**点分路径**,对复杂逻辑使用显式 `$and`/`$or`。 - 避免在热路径上调用 `describeIndex()`。`count` 通过分页的 `ListVectors` 计算(**O(n)**)。 - 仅在需要原始 Vector 时使用 `includeVector: true`。 ## 相关内容 - [元数据过滤器](https://mastra.zisheng.pro/reference/rag/metadata-filters)