在 Amazon OpenSearch Service 中搜索 k 最近邻 (k-NN)。 - Amazon OpenSearch Service

在 Amazon OpenSearch Service 中搜索 k 最近邻 (k-NN)。

Amazon OpenSearch Service 的 k-NN 简称为其关联的 k 最近邻算法,允许您搜索矢量空间中的点,并通过欧氏距离或余弦相似性查找这些点的“最近邻域”。使用案例包括推荐(例如,音乐应用程序中的“您可能喜欢的其他歌曲”功能)、图像识别和欺诈检测。

注意

本文档介绍了 OpenSearch Service 与各种版本的 k-nn 插件之间的版本兼容性,以及将该插件与托管式 OpenSearch Service 一起使用时的限制。有关 k-nn 插件的全面文档,包括简单和复杂的示例、参数参考以及该插件的完整 API 参考,请参阅开源 OpenSearch 文档。该开源文档还介绍了有关性能微调和 K-NN 特定集群设置的信息。

使用下表查找在您的 Amazon OpenSearch Service 域中运行的 k-NN 插件版本。每个 k-NN 插件版本对应于 OpenSearchElasticsearch 版本。

OpenSearch
OpenSearch 版本 k-NN 插件版本 显著功能
2.13 2.13.0.0

2.1.1 2.11.0.0

添加对 k-NN 查询中 ignore_unmapped 的支持

2.9 2.9.0.0 使用 Faiss 引擎实现了 k-NN 字节向量和高效过滤
2.7 2.7.0.0
2.5 2.5.0.0 针对 k-NN 模型系统索引进行了扩展,SystemIndexPlugin 为核心 HybridFS 添加了特定于 Lucene 的文件扩展名
2.3 2.3.0.0
1.3 1.3.0.0
1.2 1.2.0.0 增加了对 Faiss 库的支持
1.1 1.1.0.0
1.0

1.0.0.0

已重命名 REST API,同时支持向后兼容性,将命名空间重命名从 opendistroopensearch
Elasticsearch
Elasticsearch 版本 k-NN 插件版本 显著功能
7.1

1.3.0.0

欧氏距离
7.4

1.4.0.0

7.7

1.8.0.0

余弦相似性
7.8

1.9.0.0

7.9

1.11.0.0

热身 API,自定义评分

7.10

1.13.0.0

Hamming 距离、L1 Norm 距离、Painless 脚本

k-NN 入门

要使用 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 } } } }

如果您需要在保持最佳性能的同时处理大量查询,则可以使用 _msearch 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 查询设置批量向量搜索。

k-NN 差异、调整和限制

OpenSearch 允许您使用 _cluster/settings API 修改所有 k-NN 设置。在 OpenSearch Service 上,您可以更改除 knn.memory.circuit_breaker.enabledknn.circuit_breaker.triggered 之外的所有设置。k-NN 统计数据作为 Amazon CloudWatch 指标包括在内。

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

如果索引使用的是近似 k-NN("index.knn": true),您不能将 k-NN 索引迁移到 UltraWarm 或者冷存储。如果 index.knn 已设为 false准确 k-NN),则您可以将索引移至其他存储层。