

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# Amazon DocumentDB 向量搜索
<a name="vector-search"></a>

向量搜索是机器学习使用的一种方法，它通过使用距离或相似度指标比较向量表示来查找与给定数据点相似的数据点。两个向量在向量空间中越接近，就可以认为底层项目就越相似。这种方法有助于捕捉数据的语义意义。这种方法在推荐系统、自然语言处理和图像识别等各种应用中都很有用。

Amazon DocumentDB 向量搜索兼有 JSON 文档数据库的灵活性和丰富的查询功能，以及向量搜索的强大功能。如果要使用现有的 Amazon DocumentDB 数据或灵活的文档数据结构来构建机器学习和生成式人工智能用例，例如语义搜索体验、产品推荐、个性化、聊天机器人、欺诈检测和异常检测，Amazon DocumentDB 向量搜索就是您的理想之选。Amazon DocumentDB 5.0 基于实例的集群可以使用向量搜索。

**Topics**
+ [插入向量](#w2aac21c11b9)
+ [创建向量索引](#w2aac21c11c11)
+ [获取索引定义](#w2aac21c11c13)
+ [查询向量](#w2aac21c11c15)
+ [特征和限制](#vector-limitations)
+ [最佳实践](#w2aac21c11c19)

## 插入向量
<a name="w2aac21c11b9"></a>

要在 Amazon DocumentDB 数据库插入向量，可以使用现有的插入方法：

**示例**

以下示例在测试数据库中创建了一个包含五个文档的集合。每个文档都含有两个字段：产品名称及其相应的向量嵌入。

```
db.collection.insertMany([
  {"product_name": "Product A", "vectorEmbedding": [0.2, 0.5, 0.8]},
  {"product_name": "Product B", "vectorEmbedding": [0.7, 0.3, 0.9]},
  {"product_name": "Product C", "vectorEmbedding": [0.1, 0.2, 0.5]},
  {"product_name": "Product D", "vectorEmbedding": [0.9, 0.6, 0.4]},
  {"product_name": "Product E", "vectorEmbedding": [0.4, 0.7, 0.2]}
]);
```

## 创建向量索引
<a name="w2aac21c11c11"></a>

Amazon DocumentDB 支持分层可导航小世界 (HNSW) 索引和使用平面压缩 () 索引方法的倒置文件。IVFFlat IVFFlat 索引将向量分成列表，然后搜索这些列表中最接近查询向量的选定子集。另一方面，HNSW 索引则将向量数据组织成多层次的图。尽管与之相比，HNSW 的构建时间较慢 IVFFlat，但它提供了更好的查询性能和召回率。与之不同的是 IVFFlat，HNSW 不涉及训练步骤，因此无需加载任何初始数据即可生成索引。对于大多数用例，建议使用 HNSW 索引类型进行向量搜索。

如果不创建向量索引，Amazon DocumentDB 会进行精确的近邻搜索，从而确保完美的查全率。但是，速度在生产场景中至关重要。我们建议使用向量索引，这样可以牺牲一些查全率来提高速度。值得注意的是，添加向量索引可能会产生不同的查询结果。

**模板**

您可以使用以下 `createIndex` 或 `runCommand` 模板，在向量字段上构建向量索引：

------
#### [ Using createIndex ]

在某些驱动程序中，比如 mongosh 和 Java，使用 `createIndex` 中的参数 `vectorOptions` 可能会导致错误。在这种情况下，建议使用 `runCommand`：

```
db.collection.createIndex(
  { "<vectorField>": "vector" },
  { "name": "<indexName>",
    "vectorOptions": {
      "type": " <hnsw> | <ivfflat> ",
      "dimensions": <number_of_dimensions>,
      "similarity": " <euclidean> | <cosine> | <dotProduct> ",
      "lists": <number_of_lists> [applicable for IVFFlat],
      "m": <max number of connections> [applicable for HNSW],
      "efConstruction": <size of the dynamic list for index build> [applicable for HNSW]
    }
  }
);
```

------
#### [ Using runCommand ]

在某些驱动程序中，比如 mongosh 和 Java，使用 `createIndex` 中的参数 `vectorOptions` 可能会导致错误。在这种情况下，建议使用 `runCommand`：

```
db.runCommand(
  { "createIndexes": "<collection>", 
  "indexes": [{
      key: { "<vectorField>": "vector" },
      vectorOptions: {
          type: " <hnsw> | <ivfflat> ",
          dimensions: <number of dimensions>,
          similarity: " <euclidean> | <cosine> | <dotProduct> ",
          lists: <number_of_lists> [applicable for IVFFlat],
          m: <max number of connections> [applicable for HNSW],
          efConstruction: <size of the dynamic list for index build> [applicable for HNSW]
          },
      name: "myIndex" 
      }] 
  }
);
```

------


| 参数 | 要求 | 数据类型 | 说明 | 值 | 
| --- | --- | --- | --- | --- | 
|  **name**  |  optional  |  字符串  |  指定索引的名称。  |  字母数字  | 
|  **type**  |  optional  |    |  指定索引类型。  |  支持：HNSW 或 IVFFLAT 默认：HNSW（引擎修补版本 3.0.4574 及更高版本）  | 
|  **dimensions**  |  必需  |  整数  |  指定向量数据中的维度数。  |  最多 2,000 个维度。  | 
|  **similarity**  |  必需  |  字符串  |  指定相似度计算使用的距离指标。  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/documentdb/latest/developerguide/vector-search.html)  | 
|  **lists**  |  必需的 IVFFlat  |  整数  |  指定 IVFFlat 索引用于对矢量数据进行分组的聚类数。对于不到 100 万个文档，推荐设置为文档数量/1000，超过 100 万个文档的设置为 `sqrt(# of documents)`。  |  最小值：1 最大值：请参阅下文 [特征和限制](#vector-limitations) 中各实例类型列表的表格。  | 
|  **m**  |  optional  |  整数  |  指定 HNSW 索引的最大连接数  |  默认值：16 范围：[2, 100]  | 
|  **efConstruction**  |  optional  |  整数  |  指定用于构建 HNSW 索引图的动态候选列表的大小。 `efConstruction` 必须大于或等于 (2 \$1 m)。  |  默认值：64 范围：[4, 1000]  | 

请务必适当设置 for IVFFlat `m` 和 for HNSW 等`lists`子参数`efConstruction`的值，因为这会影响搜索的准确性/召回率、构建时间和性能。列表值越大，查询速度越快，因为这可以减少每个列表中的向量数量，从而产生较小的区域。但是，较小的区域可能会产生更多的查全错误，从而降低准确度。对于 HNSW 来说，增加 `efConstruction` 和 `m` 的值可提高准确度，但也会增加索引构建的时间和大小。请参阅以下示例：

**示例**

------
#### [ HNSW ]

```
db.collection.createIndex(
  { "vectorEmbedding": "vector" },
  { "name": "myIndex",
    "vectorOptions": {
      "type": "hnsw",
      "dimensions": 3,
      "similarity": "euclidean",
      "m": 16,
      "efConstruction": 64
    }
  }
);
```

------
#### [ IVFFlat ]

```
db.collection.createIndex(
  { "vectorEmbedding": "vector" },
  { "name": "myIndex",
    "vectorOptions": {
      "type": "ivfflat",
      "dimensions": 3,
      "similarity": "euclidean",
      "lists":1
    }
  }
)
```

------

## 获取索引定义
<a name="w2aac21c11c13"></a>

您可以使用以下 `getIndexes` 命令查看索引的详细信息，包括向量索引：

**示例**

```
db.collection.getIndexes()
```

**示例输出**

```
[
 {
  "v" : 4,
  "key" : {
   "_id" : 1
  },
  "name" : "_id_",
  "ns" : "test.collection"
 },
 {
  "v" : 4,
  "key" : {
   "vectorEmbedding" : "vector"
  },
  "name" : "myIndex",
  "vectorOptions" : {
   "type" : "ivfflat",
   "dimensions" : 3,
   "similarity" : "euclidean",
   "lists" : 1
  },
  "ns" : "test.collection"
 }
]
```

## 查询向量
<a name="w2aac21c11c15"></a>

Amazon DocumentDB 支持两个向量搜索运算符来查询向量：

### 经典矢量搜索运算符
<a name="w2aac21c11c15b5"></a>

使用以下模板查询向量：

```
db.collection.aggregate([
  {
    $search: {
      "vectorSearch": {
        "vector": <query vector>, 
        "path": "<vectorField>", 
        "similarity": "<distance metric>",
        "k": <number of results>,
        "probes":<number of probes> [applicable for IVFFlat],
        "efSearch":<size of the dynamic list during search> [applicable for HNSW]
      }
    }
  }
]);
```


| 参数 | 要求 | Type | 说明 | 值 | 
| --- | --- | --- | --- | --- | 
|  **vectorSearch**  |  必需  |  operator  |  在 \$1search 命令中用于查询向量。  |    | 
|  **vector**  |  必需  |  array  |  表示可用于查找相似向量的查询向量。  |    | 
|  **path**  |  必需  |  字符串  |  定义向量字段的名称。  |    | 
|  **k**  |  必需  |  整数  |  指定搜索返回的最大结果数量。  |    | 
|  **similarity**  |  必需  |  字符串  |  指定相似度计算使用的距离指标。  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/documentdb/latest/developerguide/vector-search.html)  | 
|  **probes**  |  optional  |  整数  |  需要向量搜索检查的集群数量。值越大，查全率越好，但会牺牲速度。可以将其设置为列表数量，以进行精确的近邻搜索（此时计划程序不会使用索引）。开始微调的推荐设置为 `sqrt(# of lists)`。  |  默认：1  | 
|  **efSearch**  |  optional  |  整数  |  指定 HNSW 索引在搜索期间使用的动态候选列表的大小。`efSearch` 的值越大，查全率越好，但会牺牲速度。  |  原定设置值：40 范围：[1, 1000]  | 

必须微调 `efSearch` (HNSW) 或 `probes` (IVFFlat) 的值，以实现所需的性能和精度。请参阅以下示例操作：

------
#### [ HNSW ]

```
db.collection.aggregate([
  {
    $search: {
      "vectorSearch": {
        "vector": [0.2, 0.5, 0.8], 
        "path": "vectorEmbedding", 
        "similarity": "euclidean",
        "k": 2,
        "efSearch": 40
      }
    }
  }
]);
```

------
#### [ IVFFlat ]

```
db.collection.aggregate([
  {
    $search: {
      "vectorSearch": {
        "vector": [0.2, 0.5, 0.8], 
        "path": "vectorEmbedding", 
        "similarity": "euclidean",
        "k": 2,
        "probes": 1
      }
    }
  }
]);
```

------

**示例输出**

此操作的输出将类似于以下内容：

```
{ "_id" : ObjectId("653d835ff96bee02cad7323c"), "product_name" : "Product A", "vectorEmbedding" : [ 0.2, 0.5, 0.8 ] }
{ "_id" : ObjectId("653d835ff96bee02cad7323e"), "product_name" : "Product C", "vectorEmbedding" : [ 0.1, 0.2, 0.5 ] }
```

### `$vectorSearch`操作员（在亚马逊 DocumentDB 8.0 及更高版本中可用）
<a name="w2aac21c11c15b7"></a>

使用以下模板查询向量：

```
db.collection.aggregate([
{
  "$vectorSearch": {
    "exact": true | false,
    "index": "<index-name>" [supports only HNSW index],
    "limit": <number-of-results> [same as k],
    "path": "<vector field-to-search>",
    "queryVector": <array-of-numbers>,
    "numCandidates": <number-of-candidates> [same as efSearch], 
  }
}])
```

## 特征和限制
<a name="vector-limitations"></a>

**版本兼容性**
+ 亚马逊 DocumentDB 的矢量搜索仅适用于基于实例的亚马逊 DocumentDB 5.0 以上集群。

**向量**
+ Amazon DocumentDB 最多可以为 2,000 个维度的向量编制索引。但是，如果不使用索引，可以存储多达 16,000 个维度。

**索引**
+ 对于创建 IVFFlat 索引，列表参数的推荐设置为文档数/1000（对于最多 100 万个文档和`sqrt(# of documents)`超过 100 万个文档）。由于工作内存的限制，Amazon DocumentDB 支持的某个最大列表参数值具体取决于维度的数量。下表为 500、1000 和 2,000 个维度的向量提供了列表参数最大值，以供您参考：    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/documentdb/latest/developerguide/vector-search.html)
+ 向量索引不支持 `compound`、`sparse` 或 `partial` 等其他索引选项。
+ 在亚马逊 DocumentDB 5.0 中，HNSW 索引不支持并行索引构建。

**向量查询**
+ 对于向量搜索查询，务必微调 `probes` 或 `efSearch` 等参数才能获得最佳结果。`probes` 或 `efSearch` 参数的值越大，查全率越高，速度就越低。开始微调探针参数的推荐设置为 `sqrt(# of lists)`。

## 最佳实践
<a name="w2aac21c11c19"></a>

了解在 Amazon DocumentDB 中使用向量搜索的最佳实践。随着新的最佳实践的确定，此节将不断更新。
+ 使用平面压缩的倒置文件 (IVFFlat) 索引创建涉及根据相似性对数据点进行聚类和组织。因此，为了使索引更加有效，建议在创建索引之前至少加载一些数据。
+ 对于向量搜索查询，务必微调 `probes` 或 `efSearch` 等参数才能获得最佳结果。`probes` 或 `efSearch` 参数的值越大，查全率越高，速度就越低。开始微调 `probes` 参数的推荐设置为 `sqrt(lists)`。

**资源**
+ [向量搜索最新消息博客文章](https://aws.amazon.com/blogs/aws/vector-search-for-amazon-documentdb-with-mongodb-compatibility-is-now-generally-available)
+ [语义搜索代码示例](https://github.com/aws-samples/amazon-documentdb-samples/tree/master/blogs/semanticsearch-docdb)
+ [Amazon DocumentDB 向量搜索代码示例](https://github.com/aws-samples/amazon-documentdb-samples/tree/master/samples/vector-search)