

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

# 在亚马逊服务中搜索 k 最近邻 (k-nn) OpenSearch
<a name="knn"></a>

Amazon S OpenSearch ervice 的 *k-nn 是其关联的 k 最近邻*算法的缩写，它允许您在向量空间中搜索点，并通过欧几里得距离或余弦相似度找到这些点的 “最近邻”。使用案例包括推荐（例如，音乐应用程序中的“您可能喜欢的其他歌曲”功能）、图像识别和欺诈检测。

**注意**  
本文档简要概述了 k-nn 插件，以及在托管 OpenSearch 服务中使用该插件时的限制。[有关 k-nn 插件的全面文档，包括简单和复杂的示例、参数参考以及完整的 API 参考，请参阅开源OpenSearch 文档。](https://opensearch.org/docs/latest/search-plugins/knn/index/)开源文档还涵盖了性能调整和 k-NN-specific集群设置。

## k-NN 入门
<a name="knn-gs"></a>

要使用 k-NN，您必须使用 `index.knn` 设置创建索引，然后添加一个或多个数据类型为 `knn_vector` 的字段。

```
PUT my-index

{
  "settings": {
    "index.knn": true
  },
  "mappings": {
    "properties": {
      "my_vector1": {
        "type": "knn_vector",
        "dimension": 2
      },
      "my_vector2": {
        "type": "knn_vector",
        "dimension": 4
      }
    }
  }
}
```

`knn_vector` 数据类型支持最多 10,000 个浮点数的单个列表，浮点数的数量由所需的 `dimension` 参数定义。创建索引后，向其中添加一些数据。

```
POST _bulk

{ "index": { "_index": "my-index", "_id": "1" } }
{ "my_vector1": [1.5, 2.5], "price": 12.2 }
{ "index": { "_index": "my-index", "_id": "2" } }
{ "my_vector1": [2.5, 3.5], "price": 7.1 }
{ "index": { "_index": "my-index", "_id": "3" } }
{ "my_vector1": [3.5, 4.5], "price": 12.9 }
{ "index": { "_index": "my-index", "_id": "4" } }
{ "my_vector1": [5.5, 6.5], "price": 1.2 }
{ "index": { "_index": "my-index", "_id": "5" } }
{ "my_vector1": [4.5, 5.5], "price": 3.7 }
{ "index": { "_index": "my-index", "_id": "6" } }
{ "my_vector2": [1.5, 5.5, 4.5, 6.4], "price": 10.3 }
{ "index": { "_index": "my-index", "_id": "7" } }
{ "my_vector2": [2.5, 3.5, 5.6, 6.7], "price": 5.5 }
{ "index": { "_index": "my-index", "_id": "8" } }
{ "my_vector2": [4.5, 5.5, 6.7, 3.7], "price": 4.4 }
{ "index": { "_index": "my-index", "_id": "9" } }
{ "my_vector2": [1.5, 5.5, 4.5, 6.4], "price": 8.9 }
```

然后，您可以使用 `knn` 查询类型搜索数据。

```
GET my-index/_search
{
  "size": 2,
  "query": {
    "knn": {
      "my_vector2": {
        "vector": [2, 3, 5, 6],
        "k": 2
      }
    }
  }
}
```

在这种情况下，`k` 是您希望查询返回的邻居数，但您还必须包含 `size` 选项。否则，您将获得针对每个分区（和每个分段）的 `k` 个结果，而不是针对整个查询的 `k` 个结果。k-NN 支持的最大 `k` 值为 10,000。

如果将 `knn` 查询与其他子句混合，则收到的结果数可能少于 `k` 个。在此示例中，`post_filter` 子句将结果数从 2 减少到 1。

```
GET my-index/_search

{
  "size": 2,
  "query": {
    "knn": {
      "my_vector2": {
        "vector": [2, 3, 5, 6],
        "k": 2
      }
    }
  },
  "post_filter": {
    "range": {
      "price": {
        "gte": 6,
        "lte": 10
      }
    }
  }
}
```

如果您需要在保持最佳性能的同时处理大量查询，则可以使用 [https://opensearch.org/docs/latest/api-reference/multi-search/](https://opensearch.org/docs/latest/api-reference/multi-search/) API，借助 JSON 构建批量搜索，然后发送单个请求以执行多个搜索：

```
GET _msearch

{ "index": "my-index"}
{ "query": { "knn": {"my_vector2":{"vector": [2, 3, 5, 6],"k":2 }} } }
{ "index": "my-index", "search_type": "dfs_query_then_fetch"}
{ "query": { "knn": {"my_vector1":{"vector": [2, 3],"k":2 }} } }
```

以下视频演示了如何为 K-NN 查询设置批量向量搜索。

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/Umi67JCfCbU/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/Umi67JCfCbU)


## k-NN 差异、调整和限制
<a name="knn-settings"></a>

OpenSearch 允许您使用 API 修改所有 [k-nn 设置](https://docs.opensearch.org/latest/vector-search/settings/)。`_cluster/settings`在 OpenSearch 服务中，您可以更改除`knn.memory.circuit_breaker.enabled`和之外的所有设置`knn.circuit_breaker.triggered`。k-nn 统计数据包含在 A [ma CloudWatch ](managedomains-cloudwatchmetrics.md) zon 指标中。

特别是，根据`knn.memory.circuit_breaker.limit`统计数据和该实例类型的可用 RAM 检查每个数据节点上的`KNNGraphMemoryUsage`指标。 OpenSearch 服务将实例内存的一半用于 Java 堆（堆大小不超过 32 GiB）。默认情况下，k-NN 使用最多 50% 的剩余一半，因此具有 32 GiB RAM 的实例类型可以容纳 8 GiB 的图形 (32 \$1 0.5 \$1 0.5)。如果图形内存使用量超过此值，性能可能会受到影响。

您可以将在 2.x 或更高版本上创建的 k-nn 索引迁移到版本 2.17 [UltraWarm](ultrawarm.md)或更高版本的域中或在域上进行[冷存储](cold-storage.md)。

对于热索引，k-nn 索引的清除缓存 api 和预热 api 会遭阻止。当首次对索引启动查询时，系统会从 Amazon S3 下载图形文件并将图形加载到内存中。同样，当图形的 TTL 到期时，文件会自动从内存中删除。