Elastic 采用近似最近邻 (ANN) 技术,极大地提高了生产工作负载的性能。
尝鲜体验:
一:集群搭建
见 02-服务器安装
二:索引和API
1:索引和数据
1:使用向量函数(script),支持复杂计算
详细见:
PUT my-index
{
"mappings": {
"properties": {
"my_vector": {
"type": "dense_vector",
"dims": 3
},
"my_text" : {
"type" : "keyword"
}
}
}
}
PUT my-index/_doc/1
{
"my_text" : "text1",
"my_vector" : [0.5, 10, 6]
}
PUT my-index/_doc/2
{
"my_text" : "text2",
"my_vector" : [-0.5, 10, 10]
}
在许多情况下,蛮力 kNN 搜索效率不够高。出于这个原因,该dense_vector类型支持将向量索引到专门的数据结构中,以支持通过 kNN 搜索 API进行快速 kNN 检索。index您可以通过设置参数来启用索引 :
2:使用KNN API,支持复杂计算
需要构建矢量索引,是一个相对昂贵的过程。
PUT my-index-2
{
"mappings": {
"properties": {
"my_vector": {
"type": "dense_vector",
"dims": 3,
"index": true,
"similarity": "dot_product"
}
}
}
}
启用时index,必须定义要在 KNN 搜索中使用的向量相似度。
nested如果密集向量场在映射中,则它们不能被索引 。
3:mapping 参数意义
1:dims:(必需,整数)向量维数。不能超过1024索引向量
2:index:(可选,布尔值)可以使用kNN 搜索 APItrue搜索此字段。默认为. false
3:similarity:
(必需,字符串)在 kNN 搜索中使用的向量相似度度量。文档根据其向量字段与查询向量的相似性进行排名。_score每个文档 的
如果index是true,则此参数是必需的。
l2_norm
根据向量之间的 L 2距离(也称为欧几里得距离)计算相似度。文档_score计算为 1 / (1 + l2_norm(query, vector)^2)。
dot_product
计算两个向量的点积。此选项提供了一种执行余弦相似度的优化方法。为了使用它,所有向量必须是单位长度的,包括文档向量和查询向量。文档_score计算为(1 + dot_product(query, vector)) / 2。
cosine
计算余弦相似度。请注意,执行余弦相似度的最有效方法是将所有向量归一化为单位长度,而不是使用 dot_product. 只有cosine在需要保留原始向量且无法提前对其进行归一化时才应使用。文档_score 计算为(1 + cosine(query, vector)) / 2。cosine相似性不允许具有零幅度的向量,因为在这种情况下没有定义余弦 。
4:index_options
(可选,对象)配置 kNN 索引算法的可选部分。HNSW 算法有两个影响数据结构构建方式的内部参数。可以调整这些以提高结果的准确性,但会降低索引速度。提供时index_options,必须定义其所有属性。
的属性index_options
type
(必需,字符串)要使用的 kNN 算法的类型。目前仅hnsw支持。
m
(必需,整数)每个节点将在 HNSW 图中连接到的邻居数。默认为16.
ef_construction
(必需,整数)在为每个新节点组装最近邻居列表时要跟踪的候选者数量。默认为100
三:kNN search API
API示例
GET my-index/_knn_search
{
"knn": {
"field": "image_vector",
"query_vector": [0.3, 0.1, 1.2],
"k": 10,
"num_candidates": 100
},
"_source": ["name", "file_type"]
}
描述:
kNN 搜索 API 对 dense_vector字段执行 k 最近邻 (kNN) 搜索。给定一个查询向量,它会找到k个 最接近的向量并将这些文档作为搜索命中返回。
Elasticsearch 使用HNSW 算法来支持高效的 kNN 搜索。与大多数 kNN 算法一样,HNSW 是一种近似方法,它牺牲了结果准确性以提高搜索速度。这意味着返回的结果并不总是真正的k最近邻。
kNN 搜索 API 支持和filter DSL结合使用,先使用filter做过滤。
不支持别名相关api,见:
请求参数意义
1:knn:(必需,对象)定义要运行的 kNN 查询。
knn属性:
field
(必需,字符串)要搜索的向量字段的名称。必须是 dense_vector启用索引的字段。
query_vector
(必需,浮点数组)查询向量。必须与您正在搜索的矢量字段具有相同的维数。
k
(必需,整数)作为热门匹配返回的最近邻居数。该值必须小于num_candidates。
num_candidates
(必需,整数)每个分片要考虑的最近邻候选者的数量。不能超过 10,000。Elasticsearchnum_candidates从每个分片中收集结果,然后将它们合并以找到排名靠前的k结果。增加 num_candidates往往会提高最终k结果的准确性。
2:filter
执行过滤:
3:_source
(可选)指示为匹配文档返回哪些源字段。这些字段在hits._source搜索响应的属性中返回。默认为true. 请_source参阅选项。
其他见官网描述:请求参数
响应参数意义
kNN 搜索响应与搜索 API 响应具有完全相同的结构 。但是,某些部分具有特定于 kNN 搜索的含义:
- 文档_score由查询和文档向量之间的相似性确定 。见 similarity。
- 该hits.total对象包含考虑的最近邻候选者的总数,即num_candidates * num_shards. 将 hits.total.relation始终为eq,表示精确值。
示例
构建
``` PUT my-index { “mappings”: { “properties”: {
} } }"image_vector": { "type": "dense_vector", "dims": 3, "index": true, "similarity": "l2_norm" }, "name": { "type": "keyword" }, "file_type": { "type": "keyword" }
PUT my-index/_doc/1?refresh { “image_vector” : [0.5, 0.1, 2.6], “name”: “moose family”, “file_type”: “jpeg” }
PUT my-index/_doc/2?refresh { “image_vector” : [1.0, 0.8, -0.2], “name”: “alpine lake”, “file_type”: “svg” }
<a name="USVgz"></a>
#### 搜索
GET my-index/_knn_search
{
“knn”: {
“field”: “image_vector”,
“query_vector”: [0.3, 0.1, 1.2],
“k”: 5,
“num_candidates”: 50
},
“filter”: {
“term”: {
“file_type”: “svg”
}
},
“_source”: [“name”]
}
```