在 Azure Cosmos DB for MongoDB vCore 中对嵌入使用矢量搜索

适用对象: MongoDB vCore

使用 Azure Cosmos DB for MongoDB vCore 中的矢量搜索将基于 AI 的应用程序与 Azure Cosmos DB 中存储的数据无缝集成。 通过使用矢量搜索,可以直接在 Azure Cosmos DB for MongoDB vCore 中高效地存储和查询存储的高维矢量数据并为其编制索引。 无需将数据传输到更昂贵的矢量搜索功能替代方案。

借助矢量搜索,可根据数据特征而不是属性字段上的精确匹配项来查找相似的项。 这种方法在搜索相似文本、查找相关图像、提出建议甚至是检测异常等应用中很有用。 它的工作原理是获取使用机器学习模型或使用嵌入 API 创建的数据的矢量表示形式(数字列表)。 然后,它会测量数据矢量与查询矢量之间的距离。 最接近查询矢量的数据矢量是在语义上最相似的数据矢量。

通过本机集成矢量搜索功能,可以在基于 OpenAI API 构建的应用程序中充分发挥数据的潜力。 还可以创建使用矢量嵌入的自定义生成解决方案。

使用 createIndexes 模板创建矢量索引

要创建矢量索引,请使用以下 createIndexes 模板:

{
  "createIndexes": "<collection_name>",
  "indexes": [
    {
      "name": "<index_name>",
      "key": {
        "<path_to_property>": "cosmosSearch"
      },
      "cosmosSearchOptions": {
        "kind": "vector-ivf",
        "numLists": <integer_value>,
        "similarity": "<string_value>",
        "dimensions": <integer_value>
      }
    }
  ]
}
字段 类型​​ 说明
index_name string 索引的唯一名称。
path_to_property string 包含矢量的属性的路径。 此路径可以是顶级属性或属性的点表示法路径。 如果使用点表示法路径,则所有非叶元素都不能是数组。 矢量必须是要编制索引并在矢量搜索结果中返回的 number[]
kind string 要创建的矢量索引的类型。 目前,vector-ivf 是唯一受支持的索引选项。
numLists 整型 该整数是反向文件 (IVF) 索引用于对矢量数据进行分组的群集数。 如果最多为 100 万个文档,建议将 numLists 设置为 documentCount/1000,如果超过 100 万个文档,则将其设置为 sqrt(documentCount)。 使用 1numLists 值类似于执行暴力搜索,并且其性能有限。
similarity string 用于 IVF 索引的相似性指标。 可能的选项包括 COS(余弦距离)、L2(欧几里德距离)和 IP(内积)。
dimensions 整型 矢量相似度的维度数。 支持的最大维度数是 2000

重要

要获得良好的准确性和性能,正确设置 numLists 参数非常重要。 如果最多为 100 万个文档,建议将 numLists 设置为 documentCount/1000,如果超过 100 万个文档,则将其设置为 sqrt(documentCount)

随着数据库中项数的增加,应将 numLists 调大,从而使矢量搜索实现良好的延迟性能。

如果要尝试新的方案或创建小型演示,可受限将 numLists 设置为 1,跨所有矢量执行暴力搜索。 这应该会提供最准确的矢量搜索结果,但请注意搜索速度和延迟会很慢。 初始设置后,应继续操作,按照上述指南来优化 numLists 参数。

重要

矢量必须是要编制索引的 number[]。 使用另一种类型(如 double[]),可防止对文档编制索引。 不会在矢量搜索的结果中返回未编制索引的文档。

示例

以下示例显示了如何为矢量编制索引、添加具有矢量属性的文档、执行矢量搜索以及检索索引配置。

创建矢量索引

use test;

db.createCollection("exampleCollection");

db.runCommand({
  createIndexes: 'exampleCollection',
  indexes: [
    {
      name: 'vectorSearchIndex',
      key: {
        "vectorContent": "cosmosSearch"
      },
      cosmosSearchOptions: {
        kind: 'vector-ivf',
        numLists: 3,
        similarity: 'COS',
        dimensions: 3
      }
    }
  ]
});

此命令针对存储在指定集合 exampleCollection 中的文档中的 vectorContent 属性创建 vector-ivf 索引。 cosmosSearchOptions 属性指定 IVF 矢量索引的参数。 如果文档具有存储在嵌套属性中的矢量,可以使用点表示法路径设置此属性。 例如,如果 vectorContenttext 的子属性,则可使用 text.vectorContent

将矢量添加到数据库

若要将矢量添加到数据库集合中,首先需要使用自己的模型或其他 API 创建嵌入。 在此示例中,添加了通过示例嵌入的新文档:

db.exampleCollection.insertMany([
  {name: "Eugenia Lopez", bio: "Eugenia is the CEO of AdvenureWorks.", vectorContent: [0.51, 0.12, 0.23]},
  {name: "Cameron Baker", bio: "Cameron Baker CFO of AdvenureWorks.", vectorContent: [0.55, 0.89, 0.44]},
  {name: "Jessie Irwin", bio: "Jessie Irwin is the former CEO of AdventureWorks and now the director of the Our Planet initiative.", vectorContent: [0.13, 0.92, 0.85]},
  {name: "Rory Nguyen", bio: "Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.", vectorContent: [0.91, 0.76, 0.83]},
]);

要执行矢量搜索,请在 MongoDB 查询中使用 $search 聚合管道阶段。 若要使用 cosmosSearch 索引,请使用新的 cosmosSearch 运算符。

{
  "$search": {
    "cosmosSearch": {
        "vector": <vector_to_search>,
        "path": "<path_to_property>",
        "k": <num_results_to_return>
      }
    ...
  }
}

继续上一个示例,创建另一个矢量 queryVector。 矢量搜索测量 queryVector 与文档 vectorContent 路径中的矢量之间的距离。 可以通过设置参数 k 来设置搜索返回的结果数,此处设置为 2

const queryVector = [0.52, 0.28, 0.12];
db.exampleCollection.aggregate([
  {
    $search: {
      "cosmosSearch": {
        "vector": queryVector,
        "path": "vectorContent",
        "k": 2
      },
    "returnStoredSource": true
    }
  }
]);

在此示例中,通过 Mongo shell 使用 queryVector 作为输入来执行矢量搜索。 搜索结果是与查询矢量最相似的两个项的列表,按它们的相似度得分排序。

[
  {
    _id: ObjectId("645acb54413be5502badff94"),
    name: 'Eugenia Lopez',
    bio: 'Eugenia is the CEO of AdvenureWorks.',
    vectorContent: [ 0.51, 0.12, 0.23 ]
  },
  {
    _id: ObjectId("645acb54413be5502badff97"),
    name: 'Rory Nguyen',
    bio: 'Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.',
    vectorContent: [ 0.91, 0.76, 0.83 ]
  }
]

获取矢量索引定义

要从集合中检索矢量索引定义,请使用 listIndexes 命令:

db.exampleCollection.getIndexes();

在此示例中,返回了 vectorIndex,其中包含用于创建索引的所有 cosmosSearch 参数:

[
  { v: 2, key: { _id: 1 }, name: '_id_', ns: 'test.exampleCollection' },
  {
    v: 2,
    key: { vectorContent: 'cosmosSearch' },
    name: 'vectorSearchIndex',
    cosmosSearch: {
      kind: 'vector-ivf',
      numLists: 3,
      similarity: 'COS',
      dimensions: 3
    },
    ns: 'test.exampleCollection'
  }
]

功能和限制

  • 支持的距离指标:L2(欧几里德)、内积和余弦。
  • 支持的索引方法:IVFFLAT。
  • 为最大大小为 2,000 个维度的矢量编制索引。
  • 索引仅适用于每个文档的一个矢量。

后续步骤

本指南演示了如何创建矢量索引、添加包含矢量数据的文档、执行相似性搜索以及检索索引定义。 通过使用矢量搜索,可以直接在 Azure Cosmos DB for MongoDB vCore 中高效地存储和查询高维矢量数据并为其编制索引。 借助矢量搜索,可通过矢量嵌入充分发挥数据的全部潜力,并生成更加准确、高效和强大的应用程序。