进行向量检索
在人工智能检索应用中,不仅需要通过高维向量捕捉数据的语义特征,还经常需要结合业务标签(如分类、价格、区域)进行精准筛选。标准的向量检索虽快,但在面对复杂的业务过滤或自定义评分逻辑时显得力不从心。为了解决性能与灵活性的冲突,CSS向量数据库提供了从极速近似搜索到深度重打分、再到完全自定义脚本评分的多维度查询能力。通过合理组合前置过滤以缩小搜索空间,或者利用重打分对量化后的压缩向量进行精度补偿,开发者可以在亿级数据规模下,根据业务对响应时延和召回率的不同偏好,构建出既聪明又高效的搜索引擎。
查询模式对比
为了平衡检索精度与性能,建议根据数据规模选择合适的查询方式。
| 查询模式 | 原理介绍 | 适用场景 | 支持的集群版本 |
|---|---|---|---|
| 标准向量查询 | 基于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
- 登录云搜索服务管理控制台。
- 在左侧导航栏,选择“集群管理 > Elasticsearch”。
- 在集群列表,选择目标集群,单击操作列的“Kibana”,登录Kibana。
- 在Kibana左侧导航栏选择“Dev Tools”,进入操作页面。
控制台左侧是命令输入框,其右侧的三角形图标为执行按钮,右侧区域则显示执行结果。
- OpenSearch集群登录Dashboards
- 登录云搜索服务管理控制台。
- 在左侧导航栏,选择“集群管理 > OpenSearch”。
- 在集群列表,选择目标集群,单击操作列的“Dashboards”,登录OpenSearch Dashboards。
- 在OpenSearch Dashboards左侧导航栏选择“Dev Tools”,进入操作页面。
控制台左侧是命令输入框,其右侧的三角形图标为执行按钮,右侧区域则显示执行结果。
标准向量查询
执行以下命令,在索引中寻找与目标向量最相似的前K个结果。
POST my_index/_search
{
"size":2,
"_source": false,
"query": {
"vector": {
"my_vector": {
"vector": [1, 1],
"topk":2
}
}
}
} | 参数 | 是否必选 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
| size | 否 | Integer | 10 | 指定搜索结果最终返回的数量。 |
| _source | 否 | Boolean | true | 是否返回文档的源数据。用于减少传输数据量,提升查询性能。 取值范围:
|
| 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。 取值范围:
|
| 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" }
}
}
}
}
} | 参数 | 是否必选 | 类型 | 说明 |
|---|---|---|---|
| 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" }
}
}
}
} | 参数 | 是否必选 | 类型 | 说明 |
|---|---|---|---|
| bool | 是 | Map | 布尔查询的根查询类型,用于组合多个查询条件。 键值对含义:
|
| bool.must | 是 | Map | 指定查询必须满足的条件,即查询结果必须同时满足这些条件。 键值对含义:
|
| 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"
}
}
}
}
} | 参数 | 是否必选 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
| script_score | 是 | Map | 无 | ScriptScore查询根参数。 键值对含义:
|
| source | 是 | String | 无 | script脚本名称,固定值“vector_score”,使用内置的向量相似度计算脚本。 |
| lang | 是 | String | 无 | script脚本语言类型,固定值“vector”,使用向量计算专用语言。 |
| field | 是 | String | 无 | 向量字段配置,指定用于查询的向量字段名称(如“my_vector”)。 |
| vector | 是 | Array/String | 无 | 指定用于查询的向量值。用于计算查询向量与索引向量的相似度。 支持数组形式(如 [1, 1])或Base64编码形式(如 “AAABAAACAAAD”)。 |
| metric | 否 | String | euclidean | 向量距离度量方式。定义向量之间相似度或距离的计算方法。 取值范围:
|
重打分查询
当索引使用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"
}
}
} | 参数 | 是否必选 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
| rescore | 是 | Map | 无 | 重打分参数定义。 键值对含义:
注意: 嵌套字段Nested不支持使用该方式的重打分查询,只支持通过标准向量查询实现。 |
| window_size | 否 | Integer | 100 | 精排窗口大小。向量检索将返回topk条结果,仅对前window_size条结果进行重打分精排。值越大,精排范围越广,召回率越高,但计算开销越大。 |
| field | 是 | String | 无 | 向量字段配置,指定用于查询的向量字段名称(如“my_vector”)。 |
| vector | 是 | Array/String | 无 | 指定用于查询的向量值。用于计算查询向量与索引向量的相似度。 支持数组形式(如 [1, 1])或Base64编码形式(如 “AAABAAACAAAD”)。 |
| metric | 否 | String | euclidean | 向量距离度量方式。定义向量之间相似度或距离的计算方法。 取值范围:
|
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脚本中直接使用,以构建灵活的重打分公式。
| 函数签名 | 说明 |
|---|---|
| euclidean(Float[], DocValues) | 欧式距离函数。 |
| cosine(Float[], DocValues) | 余弦相似度函数。 |
| innerproduct(Float[], DocValues) | 内积函数。 |
| hamming(String, DocValues) | 汉明距离函数。 约束限制:
|
| hammings(String, DocValues) | 汉明距离函数。 约束限制:
|