首页/AI/RAG 与向量库速查/Elasticsearch 向量检索(kNN)

Elasticsearch 向量检索(kNN)

Elasticsearch 8.x 支持 dense_vector 字段与近似 kNN 检索:字段定义 dims 与相似度,查询在 knn 段声明 number_of_candidates 与 k,可与 BM25 查询在一个请求内组合。

RAG 与向量库速查AI更新于 2026-10-13

Elasticsearch 向量检索是什么

Elasticsearch 8.x 支持 dense_vector 字段与近似 kNN 检索:字段声明维度与相似度,查询在 knn 段里给出查询向量、k 与 num_candidates。向量索引基于 HNSW,num_candidates 决定每个分片参与筛选的候选数量,值越大召回越好、延迟越高。它的独特优势是与 BM25 同引擎:可以在同一个请求里同时发出关键词查询与向量查询,由引擎合并打分,省掉应用层拼装,也便于统一排序与过滤。

基本信息

字段类型dense_vector,需声明 dims 与 similarity
相似度cosine、dot_product、l2_norm
查询参数k(返回条数)、num_candidates(每分片候选数)
底层索引8.x 起基于 HNSW
组合能力同一请求内与 BM25 查询一起提交

典型使用场景

  • 已有 ELK 体系的团队:不引入新组件就能加上语义检索
  • 混合检索:BM25 与向量两路在一次请求内合并,减少往返
  • 日志与文档统一检索:结构化过滤条件与向量语义一起用
  • 分片扩容后调参:num_candidates 需按分片数重新评估
  • 迁移评估:从 7.x 脚本评分方案升级到 8.x 原生 kNN

建索引(8.x 写法)

建索引(8.x 写法)
PUT kb_chunks
{
  "mappings": {
    "properties": {
      "content": { "type": "text" },
      "embedding": { "type": "dense_vector", "dims": 1024,
                     "index": true, "similarity": "cosine" }
    }
  }
}

kNN 检索与混合检索

kNN 检索与混合检索
POST kb_chunks/_search
{
  "knn": { "field": "embedding",
           "query_vector": [0.1, 0.2, 0.3],
           "k": 10, "num_candidates": 100 },
  "query": { "match": { "content": "索引 重建" } },
  "_source": ["content", "source"]
}

参数与影响

参数作用调整建议
dims向量维度必须与模型输出一致,建后不可改
similarity相似度算法文本检索常用 cosine
k返回条数与上下文条数预算对齐
num_candidates每分片候选数一般取 k 的数倍,按召回实测

落地与调优要点

  • 分片结构先定:num_candidates 按分片生效,扩容后必须重新评估
  • 相似度对齐:cosine 与 dot_product 的分数口径不同,阈值要分别标定
  • 混合排序:先用引擎内合并,再评估是否需要外挂重排模型
  • 版本迁移:7.x 的脚本评分做法与 8.x 原生 kNN 参数体系完全不同
num_candidates 是每分片生效的:分片数增加后实际扫描量随之放大,调参要在真实分片结构下测,不能只在小规模索引上取经验值。

易错点

  • num_candidates 设得比 k 大不了多少,近似检索召回不稳定
  • 老版本(7.x)脚本评分方式迁移到 8.x kNN 时参数体系完全不同
  • dims 与模型输出不一致,写入报错或索引构建失败
  • 分片数变化后未重新评估 num_candidates,召回与延迟同时偏离预期
  • 把向量检索的分数与 BM25 分数直接比较,未做归一化就设定阈值
  • 开启索引后写入变慢,批量灌数前未做速率评估,导入窗口被明显拉长

数据来源与参考

  • Elasticsearch 官方文档(dense_vector / kNN search)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌