Azure Cosmos DB for NoSQL 中的矢量搜索

适用范围: NoSQL

Azure Cosmos DB for NoSQL 现提供高效的矢量索引和搜索功能。 此功能旨在处理高维矢量,可在任何规模下进行高效、准确的矢量搜索。 现在可以直接将矢量与数据一起存储在文档中。 数据库中的每个文档不仅可以包含传统的无架构数据,还可以包含作为文档其他属性的高维矢量。 这种数据和矢量的并置可以实现高效的索引和搜索,因为矢量与它们所代表的数据存储在同一个逻辑单元中。 将矢量和数据放在一起简化了数据管理、AI 应用程序体系结构以及基于矢量的操作效率。

Azure Cosmos DB for NoSQL 提供了选择矢量索引方法的灵活性:

  • 对于较小、集中的矢量搜索,“扁平”或 k 最近邻精确搜索(有时也称为暴力搜索)可以提供 100% 的检索召回率。 尤其是与查询筛选器和分区键结合使用时。
  • 一种量化扁平索引,使用基于 DiskANN 的量化方法压缩矢量,以提高 kNN 搜索的效率。
  • DiskANN 是 Microsoft Research 开发的一套先进的矢量索引算法,可支持任何规模的高效、高精度矢量搜索。

在此处详细了解矢量索引编制

可使用 WHERE 子句将 Azure Cosmos DB 中的矢量搜索与所有其他受支持的 Azure Cosmos DB NoSQL 查询筛选器和索引结合使用。 这使得矢量搜索能够为应用程序提供最相关的数据。

该功能增强了 Azure Cosmos DB 的核心功能,使其在处理 AI 应用程序中的矢量数据和搜索需求方面更具通用性。

什么是矢量存储?

矢量存储或向量数据库] 是一个旨在存储和管理矢量嵌入的数据库,它是高维空间中数据的数学表示形式。 在此空间中,每个维度对应于数据的一个特征,数万个维度可用于表示复杂的数据。 矢量在此空间中的位置表示其特征。 字词、短语或整个文档、图像、音频和其他类型的数据都可以矢量化。

矢量存储的工作原理是什么?

在矢量存储中,矢量搜索算法用于查询嵌入项以及为其编制索引。 一些已知的矢量搜索算法包括分层导航小型世界 (HNSW)、倒置文件(IVF)、DiskANN 等。借助矢量搜索,可根据数据特征而不是属性字段上的精确匹配项来查找相似的项。 这种方法在搜索相似文本、查找相关图像、提出建议甚至是检测异常等应用中很有用。 它用于查询数据的矢量嵌入,这些数据是你通过嵌入 API 使用机器学习模型创建的。 矢量搜索测量数据矢量与查询矢量之间的距离。 最接近查询矢量的数据矢量是在语义上最相似的数据矢量。

在 Azure Cosmos DB for NoSQL 中的集成矢量数据库中,可以存储、查询嵌入项和原始数据并为其编制索引。 此方法避免了在单独的纯矢量数据库中复制数据产生的额外成本。 此外,此体系结构可将矢量嵌入和原始数据保存在一起,从而更好地促进多模式数据操作,并且可以实现更高的数据一致性、缩放和性能。

启用矢量索引和搜索功能

Azure Cosmos DB for NoSQL 中的矢量索引和搜索功能需要在 Azure Cosmos DB 的“功能”页面上启用。 按照以下步骤注册:

  1. 导航到 Azure Cosmos DB for NoSQL 资源页。
  2. 选择“设置”菜单项下的“功能”窗格。
  3. 选择“Azure Cosmos DB for NoSQL 中的矢量搜索”功能。
  4. 阅读该功能的说明,确认你想要启用它。
  5. 选择“启用”以开启矢量索引和搜索功能。

注意

注册请求将自动获得批准,但可能需要 15 分钟才能将帐户完全激活。

提示

或使用 Azure CLI 更新帐户的功能以支持 NoSQL 矢量搜索。

az cosmosdb update \
     --resource-group <resource-group-name> \
     --name <account-name> \
     --capabilities EnableNoSQLVectorSearch

容器矢量策略

使用 Azure Cosmos DB for NoSQL 执行矢量搜索需要为容器定义矢量策略。 这为数据库引擎提供了重要信息,使其能够对容器文档中找到的矢量执行高效的相似性搜索。 这也为矢量索引策略提供了必要的信息,如果你选择指定一个的话。 包含的矢量策略中包含以下信息:

  • “path”:包含矢量的属性(必需)。
  • “datatype”:矢量属性的数据类型(默认 Float32)。 
  • “dimensions”:路径中每个矢量的维度或长度。 路径中的所有矢量应具有相同的维度数。 (默认值 1536)。
  • “distanceFunction”:用于计算距离/相似性的指标。 支持的指标为:
    • 余弦,其值范围为 -1(最不相似)到 +1(最相似)。
    • 点积,其值范围为 -inf(最不相似)到 +inf(最相似)。
    • 欧氏距离,其值范围为 0(最相似)到 +inf(最不相似)。

注意

每个唯一路径最多可以有一个策略。 不过,可以指定多个策略,前提是它们针对不同的路径。

容器矢量策略可描述为 JSON 对象。 下面是有效容器矢量策略的两个示例:

具有单个矢量路径的策略

{
    "vectorEmbeddings": [
        {
            "path":"/vector1",
            "dataType":"float32",
            "distanceFunction":"cosine",
            "dimensions":1536
        }
    ]
}

具有两个矢量路径的策略

{
    "vectorEmbeddings": [
        {
            "path":"/vector1",
            "dataType":"float32",
            "distanceFunction":"cosine",
            "dimensions":1536
        },
        {
            "path":"/vector2",
            "dataType":"int8",
            "distanceFunction":"dotproduct",
            "dimensions":100
        }
    ]
}

矢量索引策略

矢量索引可在使用 VectorDistance 系统函数执行矢量搜索时提高效率。 使用矢量索引时,矢量搜索的延迟降低、吞吐量变高、RU 消耗量降低。 可以指定以下类型的矢量索引策略:

类型 描述 最大维度
flat 将矢量存储在与其他已创建索引的属性相同的索引上。 505
quantizedFlat 在索引上存储之前,量化(压缩)矢量。 这可以降低延迟和吞吐量,但会牺牲一点准确度。 4096
diskANN 基于 DiskANN 创建索引,实现快速高效的近似搜索。 4096

注意

quantizedFlatdiskANN 索引要求插入至少 1,000 个矢量。 这是为了确保量化过程的准确度。 如果矢量少于 1,000 个,则将改为执行完整扫描,这会导致矢量搜索查询的 RU 费用更高。

请注意以下几点:

  • 执行矢量搜索时,flatquantizedFlat 索引类型会利用 Azure Cosmos DB 的索引来存储和读取每个矢量。 flat 索引中的矢量搜索是暴力搜索,其准确度或召回率为 100%。 也就是说,可以保证在数据集中找到最相似的矢量。 但是,平面索引上的矢量存在 505 个维度的限制。

  • quantizedFlat 索引在该索引上存储量化(压缩)矢量。 使用 quantizedFlat 索引的矢量搜索也是暴力搜索,但由于矢量在添加到索引之前进行了量化,因此其准确度可能略低于 100%。 但相较于 flat 索引上的矢量搜索,使用 quantized flat 的矢量搜索应会具有更低的延迟、更高的吞吐量和更低的 RU 成本。 对于小规模方案,或者使用查询筛选器将矢量搜索的范围缩小到相对较小矢量集的方案,这是一个不错的选择。 当每个物理分区中要编制索引的矢量数约为 50,000 或更少时,建议使用 quantizedFlat。 但是,这只是一般性的指导原则,实际性能应该根据各个不同的场景进行测试。

  • diskANN 索引是专门为利用 DiskANN 的矢量定义的单独索引,DiskANN 是 Microsoft Research 开发的高性能矢量索引算法套件。 DiskANN 索引可提供一些延迟最低、吞吐量最高且 RU 成本最低的查询,同时仍保持较高的准确度。 通常,如果每个物理分区的矢量数超过 50,000 个,DiskANN 通常是所有索引类型中性能最佳的选择。

下面是有效矢量索引策略的示例:

{
    "indexingMode": "consistent",
    "automatic": true,
    "includedPaths": [
        {
            "path": "/*"
        }
    ],
    "excludedPaths": [
        {
            "path": "/_etag/?"
        },
        {
            "path": "/vector1/*"
        }
    ],
    "vectorIndexes": [
        {
            "path": "/vector1",
            "type": "diskANN"
        }
    ]
}
{
    "indexingMode": "consistent",
    "automatic": true,
    "includedPaths": [
        {
            "path": "/*"
        }
    ],
    "excludedPaths": [
        {
            "path": "/_etag/?"
        },
        {
            "path": "/vector1/*",
        },
        {
            "path": "/vector2/*",
        }
    ],
    "vectorIndexes": [
        {
            "path": "/vector1",
            "type": "quantizedFlat"
        },
        {
            "path": "/vector2",
            "type": "diskANN"
        }
    ]
}

重要

将矢量路径添加到索引策略的“excludedPaths”部分可确保优化插入性能。 不将矢量路径添加到“excludedPaths”会导致矢量插入的 RU 费用和延迟较高。

重要

矢量策略或矢量索引目前不支持通配符(*、[])。

使用 VectorDistance() 通过查询执行矢量搜索

使用所需矢量策略创建容器并将矢量数据插入容器后,可以在查询中使用 Vector Distance 系统函数进行矢量搜索。 下面是一个 NoSQL 查询的示例,该查询将相似度分数投影为别名 SimilarityScore,并按照从最相似到最不相似的顺序进行排序:

SELECT TOP 10 c.title, VectorDistance(c.contentVector, [1,2,3]) AS SimilarityScore   
FROM c  
ORDER BY VectorDistance(c.contentVector, [1,2,3])   

重要

始终在查询的 SELECT 语句中使用 TOP N 子句。 否则,矢量搜索将尝试返回明显更多的结果,这将导致查询使用更多的 RU,并且会产生比实际所需更高的延迟。

当前限制

Azure Cosmos DB for NoSQL 中的矢量索引和搜索功能存在一些限制。

  • quantizedFlatdiskANN 索引要求至少为 1,000 个矢量编制索引,以确保量化准确。 如果编制索引的矢量数少于 1,000 个,则改用完全扫描,RU 费用可能更高。
  • 使用 flat 索引类型编制索引的矢量最多可以有 505 个维度。 使用 quantizedFlatDiskANN 索引类型编制索引的矢量最多可以有 4,096 个维度。
  • quantizedFlat 索引利用与 DiskANN 相同的量化方法。
  • 矢量插入的速率应受到限制。 非常大的引入(超过 5M 个矢量)可能需要额外的索引生成时间。
  • 共享吞吐量数据库不受支持。
  • 目前,使用分析存储(以及 Synapse Link)和共享吞吐量的帐户不支持矢量索引和搜索。
  • 在容器上启用矢量索引和搜索后,无法将其禁用。

下一步