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 是每分片生效的:分片数增加后实际扫描量随之放大,调参要在真实分片结构下测,不能只在小规模索引上取经验值。