

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Amazon OpenSearch Service 中的 k 近鄰 (k-NN) 搜尋
<a name="knn"></a>

這是其相關聯的 *k 近鄰*演算法的簡稱，Amazon OpenSearch Service 的 KNN 可讓您搜尋向量空間中的點，並通過歐幾里德距離或餘弦相似度找出這些點的「近鄰」。使用案例包括建議 (例如，音樂應用程式中「其他您可能喜歡的歌曲」功能)、影像辨識和詐騙偵測。

**注意**  
本文件提供 k-NN 外掛程式的簡短概觀，以及將外掛程式與受管 OpenSearch Service 搭配使用時的限制。如需 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` 結果。KNN 支援的最大 `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/Umi67JCfCbU/0.jpg)](http://www.youtube.com/watch?v=Umi67JCfCbU)


## k-NN 差異、調校和限制
<a name="knn-settings"></a>

OpenSearch 可讓您使用 `_cluster/settings` API 來修改所有 [k-NN 設定](https://docs.opensearch.org/latest/vector-search/settings/)。在 OpenSearch Service 上，您可以變更除了 `knn.memory.circuit_breaker.enabled` 和 `knn.circuit_breaker.triggered` 之外的所有設定。包含 k-NN 統計數字作為 [Amazon CloudWatch 指標](managedomains-cloudwatchmetrics.md)。

尤其應依據 `knn.memory.circuit_breaker.limit` 統計數字和執行個體類型的可用 RAM，來檢查每個資料節點的 `KNNGraphMemoryUsage` 指標。OpenSearch Service 針對 Java 堆積使用執行個體 RAM 的一半 (堆積大小最多可達 32 GiB)。根據預設，k-NN 最高會使用剩下一半的 50%，這樣具有 32 GiB 的 RAM 的執行個體類型就能容納 8 GiB 的圖形 (32 \* 0.5 \* 0.5)。如果圖形記憶體用量超過此值，效能可能會受到影響。

您可以將 2.x 版或更新版本上建立的 k-NN 索引遷移至 2.17 版或更新版本網域上的 [UltraWarm](ultrawarm.md) 或[冷儲存](cold-storage.md)。

清除快取 API 和 k-NN 索引的暖索引會封鎖。當索引啟動第一個查詢時，它會從 Amazon S3 下載圖形檔案，並將圖形載入記憶體。同樣地，當圖形的 TTL 過期時，檔案會自動從記憶體移出。