更新时间:2024-11-19 GMT+08:00
分享

在Elasticsearch集群使用向量索引搜索数据

使用向量索引搜索数据支持多种方式。

标准查询

针对创建了向量索引的向量字段,提供了标准向量查询语法。下述查询命令将会返回所有数据中与查询向量最近的size(topk)条数据。

POST my_index/_search
{
  "size":2,
  "_source": false, 
  "query": {
    "vector": {
      "my_vector": {
        "vector": [1, 1],
        "topk":2
      }
    }
  }
}
表1 标准查询的参数说明

参数

说明

vector(第一个)

表示该查询类型为VectorQuery。

my_vector

指定了需要查询的向量字段名称。

vector(第二个)

指定查询向量的具体值,支持数组形式以及Base64编码形式的输入。

topk

topk的值通常与size保持一致。

其他可选的查询参数

通过调整不同索引的查询参数,可以获得更高的查询性能或者查询精度,其他参数请参见表2

表2 可选的查询参数说明

参数

子参数

说明

GRAPH类索引配置参数

ef

查询时考察邻居节点的队列大小。值越大查询精度越高,查询速度会变慢。默认值为200。

取值范围:(0, 100000]。

max_scan_num

扫描节点上限。值越大精度越高,查询速度变慢。默认值为10000。

取值范围:(0, 1000000]。

IVF类索引配置参数

nprobe

查询考察中心点的数目。值越大精度越高,查询速度变慢。默认值为100。

取值范围:(0, 100000]。

复合查询

向量检索支持与其他Elasticsearch子查询组合进行复合查询,包括前置过滤查询、布尔查询等方式。

前置过滤查询仅Elasticsearch 7.10.2版本的集群支持。

以下示例的查询场景:查询Top10条“my_label”的值为“red”的结果。

  • 前置过滤查询:先执行过滤条件检索,筛选出符合条件的结果;然后,对这些筛选后的候选结果进行向量相似度检索,以找出最相似的向量。
    查询示例如下:
    POST my_index/_search
    {
      "size": 10,
      "query": {
        "vector": {
          "my_vector": {
            "vector": [1, 2],
            "topk": 10,
            "filter": {
              "term": { "my_label": "red" }
            }
          }
        }
      }
    }

    如果“filter”过滤条件非常强,过滤后的中间结果集较小,则可以通过设置索引参数“index.vector.exact_search_threshold”,实现前置过滤查询切换为暴力查询以提升查询的召回率,参数介绍请参见创建向量索引

  • 布尔查询:布尔查询实际上是后置过滤查询方式。过滤条件与向量相似度检索分别独立执行,执行完成后对两者的检索结果进行合并,合并逻辑由must、should、filter等谓词决定。
    查询示例如下:
    POST my_index/_search
    {
      "size": 10,
      "query": {
        "bool": {
          "must": {
            "vector": {
              "my_vector": {
                "vector": [1, 2],
                "topk": 10
              }
            }
          },
          "filter": {
            "term": { "my_label": "red" }
          }
        }
      }
    }

ScriptScore查询

写入向量数据后,针对向量字段可以使用ScriptScore进行最近邻查询,查询语法如下所示。

前置过滤条件可以为任意查询,script_score仅针对前置过滤的结果进行遍历,计算向量相似度并排序返回。此种查询方式不使用向量索引算法,性能取决于前置过滤后中间结果集的大小,当前置过滤条件为"match_all"时,相当于全局暴力检索。

POST my_index/_search 
 { 
   "size":2, 
   "query": { 
   "script_score": { 
       "query": { 
         "match_all": {} 
       }, 
       "script": { 
         "source": "vector_score", 
         "lang": "vector", 
         "params": { 
           "field": "my_vector", 
           "vector": [1.0, 2.0], 
           "metric": "euclidean" 
         } 
       } 
     } 
   } 
 }
表3 script_score参数说明

参数

说明

source

script脚本描述,使用向量相似度打分时为固定值"vector_score"。

lang

script语法描述,使用固定值"vector"。

field

向量字段名称。

vector

查询向量数据。

metric

度量方式,可选值为:euclidean、inner_product、cosine、hamming。

默认值:euclidean。

重打分查询

当使用GRAPH_PQ索引或者IVF_GRAPH_PQ索引时,查询结果是根据PQ计算的非对称距离进行排序。CSS支持Rescore的方式对查询结果进行重打分精排,提升召回率。

假设my_index是PQ类型的索引,Rescore示例如下:

GET my_index/_search 
 { 
   "size": 10, 
   "query": { 
     "vector": { 
       "my_vector": { 
         "vector": [1.0, 2.0], 
         "topk": 100 
       } 
     } 
   }, 
   "rescore": { 
     "window_size": 100, 
     "vector_rescore": { 
       "field": "my_vector", 
       "vector": [1.0, 2.0], 
       "metric": "euclidean" 
     } 
   } 
 }
表4 Rescore参数说明

参数

说明

window_size

向量检索将会返回topk条结果,仅取前window_size条结果精排。

field

向量字段名称。

vector

查询向量数据。

metric

度量方式,可选值为:euclidean、inner_product、cosine、hamming。

默认值:euclidean。

Painless语法扩展查询

CSS扩展实现了多种向量距离计算函数,可在自定义的painless脚本中直接使用,用以构建灵活的重打分公式。

示例如下:

POST my_index/_search
{
  "size": 10,
  "query": {
    "script_score": {
      "query": {
        "match_all": {}
      },
      "script": {
        "source": "1 / (1 + euclidean(params.vector, doc[params.field]))",
        "params": {
          "field": "my_vector",
          "vector": [1, 2]
        }
      }
    }
  }
}
表5 支持的距离计算函数

函数签名

说明

euclidean(Float[], DocValues)

欧式距离函数。

cosine(Float[], DocValues)

余弦相似度函数。

innerproduct(Float[], DocValues)

内积函数。

hamming(String, DocValues)

汉明距离函数。只支持"dim_type"为"binary"的向量字段,输入的查询向量需要为Base64编码字符串格式。

相关文档