View a markdown version of this page

在 DynamoDB 中使用向量索引 - Amazon DynamoDB

在 DynamoDB 中使用向量索引

向量索引是 Amazon DynamoDB 中的一种索引,通过该索引可以对存储在表项目中的向量嵌入进行相似性搜索。与支持使用 QueryScan 操作进行精确匹配和范围查询的全局二级索引及本地二级索引不同,向量索引使用近似最近邻(ANN)搜索,查找其向量与您提供的查询向量最相似的项目。您可以通过调用 SearchVectors API 来执行这些相似性搜索,搜索会返回最相似的项目,按相似性分数排序。

借助向量索引,您可以将向量嵌入与操作数据一起存储在 DynamoDB 中,无需单独的向量数据库即可执行相似性搜索。这样便无需在 DynamoDB 与外部向量存储之间建立复杂的数据复制管道。

在管理向量索引时,您可以使用相同的现有 CreateTableUpdateTable API,并使用 VectorIndexes 参数(适用于 CreateTable)和 VectorIndexUpdates 参数(适用于 UpdateTable)。

向量索引的使用案例

向量索引支持多种涉及根据向量表示形式查找相似项目的使用案例:

  • 语义搜索:构建能够理解查询的含义而不是匹配关键字的搜索引擎。存储机器学习模型生成的文本嵌入并查找具有相似语义的内容。

  • 检索增强生成(RAG):将大语言模型(LLM)与相关知识库连接起来。将文档嵌入存储在 DynamoDB 中,并为 LLM 提示词检索最相关的上下文。

  • 推荐系统:根据产品、内容或用户的特征或行为的向量表示形式,查找相似的产品、内容或用户。

  • 人工智能代理记忆:存储对话嵌入,用来在不同会话之间维护上下文并提高人工智能代理的性能。

  • 异常和欺诈检测:将新事件与已知正常行为的嵌入进行比较以标记异常值,例如异常交易或欺诈活动。

向量索引与二级索引的比较

下表将向量索引与全局二级索引和本地二级索引进行了比较。

功能 向量索引 全局二级索引 本地二级索引
查询类型 相似性搜索 完全匹配和范围 完全匹配和范围
读取 API SearchVectors Query, Scan Query, Scan
架构 向量属性,加上可选的 SearchSchema(分区键、内联筛选条件) 分区键和可选的排序键 相同的分区键,不同的排序键
每个表的最大数量 5 20 5
容量模式 仅按需型实例 按需或预调配 按需或预调配

距离函数

创建向量索引时,您需要选择距离函数。距离函数确定 DynamoDB 如何衡量向量之间的相似性。您的选择会影响排名质量和搜索准确性。Amazon DynamoDB 支持三种距离函数。

距离函数 分数解释 最佳匹配
COSINE 分数越低表示相似度越高。该指标计算两个向量之间的余弦距离(1 减去余弦相似度)。值的范围从 0(方向完全相同)到 2(方向完全相反)。 最小分数
DOT_PRODUCT 分数越高表示相似度越高。计算两个向量之间的点积。 最高分数
EUCLIDEAN 分数越低表示相似度越高。计算两个向量之间的直线距离。 最小分数

要比较距离函数如何对相同的查询向量进行排名,请参阅距离函数如何排名结果

以下指导可帮助您为工作负载选择合适的距离函数。

COSINE

比较方向并忽略模长。将 COSINE 用于文本嵌入模型的语义相似性。这些模型在方向上对含义进行编码,向量长度可能会不同。示例包括 Amazon Titan 文本嵌入和 Cohere Embed。

COSINE 非常适合以下使用案例:

  • 对产品描述或文档进行语义搜索

  • 检索增强生成(RAG)

  • 常见问题匹配

当您不确定要使用哪个函数时,COSINE 是安全的默认选择。

DOT_PRODUCT

DOT_PRODUCT 同时区分方向和模长(向量的长度)。当您的嵌入模型文档推荐使用点积作为相似性度量时,或者您希望向量长度影响排名时,请选择 DOT_PRODUCT

DOT_PRODUCT 非常适合以下使用案例:

  • 使用受欢迎程度或置信度分数来缩放嵌入并影响排名的推荐系统

  • 文档特别推荐使用点积作为相似性度量的模型

  • 区分模长的排名,其中向量长度承载了有意义的信号

我们建议将嵌入标准化为单位长度。进行标准化后,DOT_PRODUCTCOSINE 的结果排名方式相同。只有在您希望让模长影响排名时才跳过标准化。

示例使用案例:产品推荐系统,您可以根据受欢迎程度分数来扩缩每个产品的嵌入。更受欢迎的商品会获得更长的向量,并在搜索结果中排名更高。

EUCLIDEAN

测量两个向量之间的直线距离。EUCLIDEAN 区分模长。当在嵌入空间中的绝对位置有影响时,使用此项。

EUCLIDEAN 非常适合以下使用案例:

  • 空间距离有影响的图像或音频嵌入

  • 接近重复检测

  • 聚类和异常检测

示例使用案例:从图像嵌入中查找接近重复的图像。

选择与您的嵌入模型相匹配的距离函数

如果您不确定要使用哪个函数,请查看嵌入模型的文档。使用具有代表性的数据集验证您的选择。索引创建之后就无法更改距离函数。有关更多信息,请参阅 将距离函数与您的嵌入相匹配

距离函数如何排名结果

您在创建索引时选择的距离函数决定了结果的 Score 值和排序顺序。在不同的距离函数下,相同的查询会对相同的项目给出不同的排名。以下示例使用查询向量 [1, 0, 0, 0] 对四个存储的向量进行查询。

存储的向量 COSINE(越低越相似) EUCLIDEAN(越低越相似) DOT_PRODUCT(越低越相似)
[1, 0, 0, 0] 0.0 0.0 1.0
[10, 0, 0, 0] 0.0 9.0 10.0
[0.7071, 0.7071, 0, 0] 0.29 0.77 0.71
[-1, 0, 0, 0] 2.0 2.0 -1.0

有两种行为需要注意:

  • COSINE 忽略模长。它对 [1, 0, 0, 0][10, 0, 0, 0] 的评分相同(均为 0.0),因为它们指向同一方向。对于相同的查询,EUCLIDEAN[10, 0, 0, 0] 排名到最后,因为它计算的是绝对距离,而绝对距离会随向量的模长增加。

  • DOT_PRODUCT 分数可以为负。指向相反方向的向量 ([-1, 0, 0, 0]) 分数为 -1.0。在对结果排序或对结果应用阈值时,不要假设分数总是非负数。

SearchSchema

创建向量索引时,您可以选择定义一个 SearchSchema,用于指定向量索引分区键和内联筛选条件属性。

HASH(向量索引分区键)

向量索引分区键对索引数据进行分区,用于实现独立扩展。指定向量索引分区键时,具有相同分区键值的项目将存储在一起,这使得系统能够仅搜索相关数据。在大规模下,这可以降低搜索延迟,因为搜索仅检查一部分向量空间,而不是整个索引。使用中低基数的属性,例如 CategoryCountry。您可以指定最多一个向量索引分区键。

如果您在 SearchSchema 中定义了向量索引分区键,则在调用 SearchVectors 时,必须在 SearchConditionExpression 中提供其值。

使用分区键来扩展搜索吞吐量

当您预计索引较大或搜索量较高时,请定义向量索引分区键。由于每个 SearchVectors 调用的范围限定为单个分区键值,因此将数据分布在多个分区键值上,可以让您每秒运行更多的搜索操作,并减少每次搜索检查的数据量。请参阅选择与您的查询模式匹配的分区键

INLINE_FILTER

内联筛选条件属性会投影到向量索引中,这样在搜索期间,DynamoDB 就可以在存储层进行筛选。

内联筛选条件支持 SearchConditionExpression 中的相等运算符 (=)。比较、范围和集合成员资格运算符(<><<=>>=IN)目前不可用。与向量索引分区键不同,内联筛选条件在搜索期间是可选的。

您可以创建向量索引而无需在 SearchSchema 中定义分区键。在这种情况下,每次 SearchVectors 调用都会搜索整个索引。这种方法更简单,因为您不需要 SearchConditionExpression,但它不能水平扩展。随着索引的增长,每次搜索都会检查更多的数据,从而增加延迟和成本。如果您的工作负载需要高吞吐量或索引包含大量向量,请定义分区键,从而将数据分布在各个分区中并实现独立扩展。请参阅选择与您的查询模式匹配的分区键

投影

与全局二级索引一样,向量索引支持投影,用于控制将基表中的哪些属性复制到索引中。您可在创建向量索引时指定投影。

  • KEYS_ONLY:只有基表主键属性、向量属性以及在 SearchSchema 中定义的所有内联筛选条件属性才会投影到索引中。

  • INCLUDE:除了 KEYS_ONLY 属性之外,您还可以指定其他非键属性进行投影。向量索引在创建之后便无法更改所包含的属性集合。要投影一组不同的属性,请删除索引,然后使用所需的投影重新创建索引。

  • ALL:基表中的所有属性都投影到索引中。

投影限制 SearchVectors 可以返回的内容

未投影到向量索引中的属性无法在 SearchVectors 响应中返回。如果您需要在搜索结果中包含特定属性,请将这些属性包含在投影中或使用 ALL

将向量索引与其他 DynamoDB 功能配合使用

DynamoDB Streams

在具有向量索引的表上,您可以在创建表时使用 StreamSpecification 参数或通过 UpdateTable 来启用 DynamoDB Streams。该流捕获对基表的项目级更改,其操作独立于向量索引。

全局表

您可以向全局表添加向量索引,也可以使用 UpdateTable 添加副本,来将具有向量索引的表转换为全局表。向量索引定义(包括其维度、距离函数、SearchSchema 和投影)会自动复制到每个新的副本区域。您无需在副本区域中单独创建向量索引。

您在任何副本区域中写入的项目,都会复制到其他区域并在其中建立索引。复制完成后,每个区域中的 SearchVectors 都会搜索相同的向量集合。由于向量搜索使用近似最近邻(ANN),因此对于相同的查询,即使在相同的数据上,在不同区域单独执行的搜索也可能返回略有不同的结果或顺序。其他区域中向量的复制和索引是异步的,即使对于多区域强一致性(MRSC)全局表也是如此。在完成更改传播之前,您刚刚在一个区域中写入的向量不会出现在另一个区域的 SearchVectors 结果中。

需要按需容量

向量索引需要按需容量模式,全局表也支持此模式。在已使用按需容量的表上创建向量索引和副本。

时间点故障恢复(PITR)和备份

当您通过时间点故障恢复或按需备份还原表时,DynamoDB 会还原基表数据和向量索引定义。与全局二级索引一样,DynamoDB 会从恢复的基表数据重建向量索引,而不是逐字节地复制向量索引,因此索引需要先经过回填,然后才能供搜索。请等待直至在恢复的索引上 IndexStatusACTIVEBackfillingfalse 之后,再运行 SearchVectors

生存时间 (TTL)

您可以在具有向量索引的表上使用 DynamoDB TTL。当 TTL 从基表中删除过期项目时,DynamoDB 会从向量索引中移除对应的条目,就像手动删除一样。因此,在删除操作传播到索引后,过期项目将不再出现在 SearchVectors 结果中。

导入和导出表数据

您可以将具有向量索引的表导出到 Amazon S3;导出内容包括基表项目(含存储在其上的向量属性)。将数据从 Amazon S3 导入新表时,请在导入请求中,按照与在 CreateTable 上使用的相同方法定义向量索引。DynamoDB 会在写入导入的项目时编制索引,向量索引在导入完成后变为可用。

DAX

DynamoDB Accelerator(DAX)不支持 SearchVectors 操作。请直接向 DynamoDB 发送 SearchVectors 请求,即使您的应用程序使用 DAX 进行其他读取操作也是如此。向量索引的存在不会影响基表读取的 DAX 缓存。