更新时间:2026-04-24 GMT+08:00
分享

进行向量检索

在人工智能检索应用中,不仅需要通过高维向量捕捉数据的语义特征,还经常需要结合业务标签(如分类、价格、区域)进行精准筛选。标准的向量检索虽快,但在面对复杂的业务过滤或自定义评分逻辑时显得力不从心。为了解决性能与灵活性的冲突,CSS向量数据库提供了从极速近似搜索到深度重打分、再到完全自定义脚本评分的多维度查询能力。通过合理组合前置过滤以缩小搜索空间,或者利用重打分对量化后的压缩向量进行精度补偿,开发者可以在亿级数据规模下,根据业务对响应时延和召回率的不同偏好,构建出既聪明又高效的搜索引擎。

查询模式对比

为了平衡检索精度与性能,建议根据数据规模选择合适的查询方式。

表1 查询模式对比

查询模式

原理介绍

适用场景

支持的集群版本

标准向量查询

基于HNSW等索引结构执行近似最近邻(ANN)搜索。通过预构建的层级图导航实现毫秒级内极速响应,其检索性能极高。在保持超高吞吐的同时,召回率表现优秀(仅有极细微损失),是平衡速度与精度的行业通用标准。

大规模通用搜索:如亿级图片库检索、短视频推荐,追求最佳响应速度的场景。

Elasticsearch:7.6.2、7.10.2

OpenSearch:1.3.6、2.19.0

复合查询:前置过滤(Pre-filter)

优先执行元数据过滤(如分类、区域),随后在筛选出的精准候选集内进行向量加速检索。由于大幅缩小了搜索空间,该模式不仅检索性能优异且召回率非常好,能确保返回的结果完全满足业务过滤条件。

条件约束搜索:如“仅搜索某个品牌下的相似商品”,对过滤结果准确性要求极高的业务。

Elasticsearch:7.10.2

OpenSearch:2.19.0

复合查询:布尔查询(Boolean Query)

布尔查询作为一种后置过滤查询方式,其核心机制是向量搜索与标签过滤独立运行后取交集。

简单业务组合:如融合打分,或集群版本较低无法支持前置过滤的场景。

Elasticsearch:7.6.2、7.10.2

OpenSearch:1.3.6、2.19.0

ScriptScore查询

跳过索引结构,直接对过滤后的文档集进行逐条计算(暴力检索)。由于每一条数据都经过精细化计算,其召回率可达100%;但检索耗时随数据量线性增长,性能表现较低,在大数据量下存在性能瓶颈。

小规模精排:如极小规模(万级以下)的高精度匹配,或强过滤后的二次排序。

Elasticsearch:7.6.2、7.10.2

OpenSearch:1.3.6、2.19.0

重打分查询(Rescore)

采用“先初筛、后精排”的两阶段处理逻辑。先利用向量索引快速获取较大规模的候选集,再对其中排名前N的结果进行高精度的二次排序。该机制在轻微增加计算耗时的前提下,显著提升检索精度。

大规模量化场景:针对PQ压缩算法进行精度修复,在节省内存的同时保障高召回率。

Elasticsearch:7.6.2、7.10.2

OpenSearch:1.3.6、2.19.0

Painless语法扩展

通过在自定义脚本中直接调用内置向量函数,实现复杂的加权评分公式。其检索性能与精度表现高度灵活,完全取决于脚本的复杂程度及底层索引的调用方式,支持极高维度的业务逻辑定制。

多因子综合排序:如“相似度+价格偏移+促销权重”的综合打分,需根据多重业务维度动态干预排名的场景。

Elasticsearch:7.6.2、7.10.2

OpenSearch:1.3.6、2.19.0

登录开发工具

进入Dev Tools执行DSL命令。

  • Elasticsearch集群登录Kibana
    1. 登录云搜索服务管理控制台
    2. 在左侧导航栏,选择“集群管理 > Elasticsearch”
    3. 在集群列表,选择目标集群,单击操作列的“Kibana”,登录Kibana。
    4. 在Kibana左侧导航栏选择“Dev Tools”,进入操作页面。

      控制台左侧是命令输入框,其右侧的三角形图标为执行按钮,右侧区域则显示执行结果。

  • OpenSearch集群登录Dashboards
    1. 登录云搜索服务管理控制台
    2. 在左侧导航栏,选择“集群管理 > OpenSearch”
    3. 在集群列表,选择目标集群,单击操作列的“Dashboards”,登录OpenSearch Dashboards。
    4. 在OpenSearch Dashboards左侧导航栏选择“Dev Tools”,进入操作页面。

      控制台左侧是命令输入框,其右侧的三角形图标为执行按钮,右侧区域则显示执行结果。

标准向量查询

执行以下命令,在索引中寻找与目标向量最相似的前K个结果。

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

参数

是否必选

类型

默认值

说明

size

Integer

10

指定搜索结果最终返回的数量。

_source

Boolean

true

是否返回文档的源数据。用于减少传输数据量,提升查询性能。

取值范围:
  • true:返回源字段数据。
  • false:不返回源字段数据。

query

Map

查询参数定义。

键值对含义:

vector(必填):指定查询类型为向量查询,标识查询请求为VectorQuery(向量相似度搜索),包含向量字段和查询向量值。

my_vector(必填):向量字段配置,指定用于查询的向量字段名称(如“my_vector”)。

vector(子参数)

Array/String

用于查询的目标特征向量。用于计算查询向量与索引向量的相似度。

支持数组形式(如 [1, 1])或Base64编码形式(如 “AAABAAACAAAD”)。

topk

Integer

指定返回的最相似结果数量。表示要检索的相似度最高的结果数量。

建议与“size”参数保持一致。

ef

Integer

200

图索引(HNSW)查询时考察邻居节点的候选队列大小。值越大,查询精度越高,但查询速度会变慢。

约束限制:索引算法是GRAPH类时,该参数配置才生效。即索引的“algorithm”“GRAPH”“GRAPH_PQ”“GRAPH_SQ8”“GRAPH_SQ4”

取值范围:0~100000。

max_scan_num

Integer

10000

图索引(HNSW)查询时单次查询中允许扫描的最大节点上限。值越大,精度越高,但查询速度会变慢。

约束限制:索引算法是GRAPH类时,该参数配置才生效。即索引的“algorithm”“GRAPH”“GRAPH_PQ”“GRAPH_SQ8”“GRAPH_SQ4”

取值范围:0~1000000

rescore

Boolean

false

是否启用重打分查询。PQ或SQ类索引查询时,可以通过该参数决定是否启用重打分查询,实现效果和重打分查询相同,但配置更简单。

约束限制:仅适用于Elasticsearch 7.10.2和OpenSearch 2.19.0集群,且要求镜像版本号不低于x.x.x_26.1.0_xxx。

取值范围:
  • true:启用重打分查询。
  • false:不启用重打分查询。

nprobe

Integer

100

IVF类索引查询时考察中心点向量的数量。值越大,检索精度越高,但查询速度会变慢。

约束限制:索引算法是IVF类时,该参数配置才生效。即索引的“algorithm”“IVF_GRAPH”“IVF_GRAPH_PQ”

取值范围:0~100000

复合查询:前置过滤

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

复合查询指向量检索与其他DSL查询组合使用。前置过滤是先通过业务标签(如颜色、分类)筛选文档,再在结果集中进行向量检索,找出最相似的结果。

执行以下命令,查询Top10条“my_label”的值为“red”的结果。

POST my_index/_search
{
  "size": 10,
  "query": {
    "vector": {
      "my_vector": {
        "vector": [1, 2],
        "topk": 10,
        "filter": {
          "term": { "my_label": "red" }
        }
      }
    }
  }
}
表3 前置过滤的参数说明

参数

是否必选

类型

说明

filter

Map

向量查询的过滤条件。

键值对含义:Key为过滤算子(如term、range),Value为具体的过滤条件定义。

如果“filter”过滤条件非常强,过滤后的中间结果集较小,则可以通过给向量索引配置“index.vector.exact_search_threshold”参数,当过滤后的结果集数量低于阈值时,系统会自动切换为暴力搜索(FLAT算法),以确保较高的召回率。配置操作请参见创建向量索引

term

Map

term过滤条件,用于精确过滤标签数据。

键值对含义:Key为字段名,Value为匹配的精确值。

例如 “{"term": {"my_label": "red"}} ”表示只返回“my_label”字段值为“red”的文档。

复合查询:布尔查询

复合查询指向量检索与其他DSL查询组合使用。布尔查询实际上是后置过滤查询方式。过滤条件与向量相似度检索分别独立执行,执行完成后对两者的检索结果进行布尔逻辑合并,合并逻辑由must、should、filter等谓词决定。

执行以下命令,查询Top10条“my_label”的值为“red”的结果。

POST my_index/_search
{
  "size": 10,
  "query": {
    "bool": {
      "must": {
        "vector": {
          "my_vector": {
            "vector": [1, 2],
            "topk": 10
          }
        }
      },
      "filter": {
        "term": { "my_label": "red" }
      }
    }
  }
}
表4 布尔查询的参数说明

参数

是否必选

类型

说明

bool

Map

布尔查询的根查询类型,用于组合多个查询条件。

键值对含义:
  • must:必须满足的条件。
  • filter:用于过滤的条件,不影响评分。
  • should:可选条件,满足越多越好。
  • must_not:必须不满足的条件。

bool.must

Map

指定查询必须满足的条件,即查询结果必须同时满足这些条件。

键值对含义:
  • vector:向量查询条件。
  • my_vector:指定向量字段名。
  • topk:返回的最相似结果数量。

bool.filter

Map

向量查询的过滤条件,用于过滤文档但不影响评分。

ScriptScore查询

基于前置查询的结果集,逐条通过脚本计算向量相似度。此种查询方式不使用向量检索算法,性能取决于前置查询的结果集大小,当前置过滤条件为"match_all"时,相当于全局暴力检索。

执行以下命令,进行暴力查询获取2条向量数据。

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" 
         } 
       } 
     } 
   } 
 }
表5 ScriptScore查询的参数说明

参数

是否必选

类型

默认值

说明

script_score

Map

ScriptScore查询根参数。

键值对含义:
  • query:前置过滤条件。当前置过滤条件为“match_all”时,相当于全局暴力检索。
  • script:脚本计算逻辑。

source

String

script脚本名称,固定值“vector_score”,使用内置的向量相似度计算脚本。

lang

String

script脚本语言类型,固定值“vector”,使用向量计算专用语言。

field

String

向量字段配置,指定用于查询的向量字段名称(如“my_vector”)。

vector

Array/String

指定用于查询的向量值。用于计算查询向量与索引向量的相似度。

支持数组形式(如 [1, 1])或Base64编码形式(如 “AAABAAACAAAD”)。

metric

String

euclidean

向量距离度量方式。定义向量之间相似度或距离的计算方法。

取值范围:

  • euclidean:欧式距离。
  • inner_product:内积距离。
  • cosine:余弦距离。
  • hamming:汉明距离,仅支持向量索引的“dim_type”“binary”时使用。

重打分查询

当索引使用GRAPH_PQ或IVF_GRAPH_PQ算法时,重打分查询时先用压缩向量快速初筛,再用原始向量对TopK结果进行精确打分,提升召回率。

假设my_index是PQ类型的索引,执行以下命令,进行重打分查询获取10条数据。

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" 
     } 
   } 
 }
表6 重打分查询的参数说明

参数

是否必选

类型

默认值

说明

rescore

Map

重打分参数定义。

键值对含义:
  • window_size:精排窗口大小。
  • vector_rescore:向量重打分配置。
注意:

嵌套字段Nested不支持使用该方式的重打分查询,只支持通过标准向量查询实现。

window_size

Integer

100

精排窗口大小。向量检索将返回topk条结果,仅对前window_size条结果进行重打分精排。值越大,精排范围越广,召回率越高,但计算开销越大。

field

String

向量字段配置,指定用于查询的向量字段名称(如“my_vector”)。

vector

Array/String

指定用于查询的向量值。用于计算查询向量与索引向量的相似度。

支持数组形式(如 [1, 1])或Base64编码形式(如 “AAABAAACAAAD”)。

metric

String

euclidean

向量距离度量方式。定义向量之间相似度或距离的计算方法。

取值范围:

  • euclidean:欧式距离。
  • inner_product:内积距离。
  • cosine:余弦距离。
  • hamming:汉明距离,仅支持向量索引的“dim_type”“binary”时使用。

Painless语法扩展查询

通过脚本扩展查询在自定义评分公式中嵌入向量距离函数,实现复杂的业务逻辑。

执行以下命令,进行Painless语法扩展查询获取10条向量数据。

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]
        }
      }
    }
  }
}

表7所示,CSS服务支持多种向量距离计算函数,可在自定义的Painless脚本中直接使用,以构建灵活的重打分公式。

表7 支持的距离计算函数

函数签名

说明

euclidean(Float[], DocValues)

欧式距离函数。

cosine(Float[], DocValues)

余弦相似度函数。

innerproduct(Float[], DocValues)

内积函数。

hamming(String, DocValues)

汉明距离函数。

约束限制:
  • 只支持“dim_type”“binary”的向量字段,输入的查询向量需要为Base64编码字符串格式。
  • 仅适用于Elasticsearch 7.6.2、Elasticsearch 7.10.2、OpenSearch 1.3.6集群。

hammings(String, DocValues)

汉明距离函数。

约束限制:
  • 只支持“dim_type”“binary”的向量字段,输入的查询向量需要为Base64编码字符串格式。
  • 仅适用于OpenSearch 2.19.0集群。

相关文档