Elasticsearch / OpenSearch 向量检索手册

向量数据库手册 02-融合型向量能力 23.1 KB 原文

Elasticsearch / OpenSearch 向量检索手册

适用版本:Elasticsearch 9.5.6(同期维护 9.4.9 / 8.19.24);OpenSearch 3.9.0(2.x 维护分支 2.19.7),核实于 2026-11 许可与形态:ES = Elastic License 2.0(默认)/ 源码可选 SSPLv1、AGPLv3,客户端 Apache-2.0;OpenSearch = Apache-2.0(官方 LICENSE 正文未直接核验);均为已有搜索集群上的向量字段 / 插件能力,分布式 一句话定位:在已有 ES / OpenSearch 索引里加一个向量字段,用同一套查询 DSL 同时做全文检索与 kNN 近邻,不新增一套数据库。 约定:$ 普通用户、# root 或 sudo、<xxx> 为占位符;标 ⚠️ 的是高危操作。 更新时间:2026-11(版本与 API 变化快,执行前请以官方文档复核)


目录

  1. 它是什么、什么时候选它
  2. 版本、许可与官方入口
  3. 安装与启动
  4. 核心概念与数据模型
  5. 快速上手:完整 CRUD 示例
  6. 索引与检索进阶
  7. 生产部署与运维
  8. 高频故障与排障
  9. 常见坑与避坑清单
  10. 速查表
  11. 参考与延伸

1. 它是什么、什么时候选它

1.1 定位与架构(按子产品)

Elasticsearch:向量是 dense_vector 字段类型,与倒排索引同处 Lucene 段内;knn query / retriever 在同一查询 DSL 内与全文检索组合,无独立进程、端口或存储,向量索引由 Lucene 段管理。index_options.type 决定 HNSW / 量化 / flat 等索引形态。

OpenSearch:向量能力由 k-NN 插件提供,索引级开关 settings.index.knn: true,字段类型 knn_vector;底层引擎可选 lucene / faiss(HNSW + IVF + PQ)/ nmslib(已弃用),IVF 需 Train API 训练模型。同样复用现有集群的分片、副本与查询 DSL。

分层 共同形态 运维含义
进程层 向量检索在搜索节点 data node 内执行 无额外进程,复用集群连接池与线程池
存储层 向量随文档存 Lucene 段,索引由段管理 随分片 / 副本复制,备份沿用集群快照
接口层 REST + 查询 DSL 复用现有客户端,无独立向量服务端口
部署层 ES 内置字段类型 / OpenSearch 插件开关 升级 = 升集群或插件,不新增组件

1.2 横向对照表:定位差异(第 1 章)

维度 Elasticsearch OpenSearch
向量字段类型 dense_vector knn_vector
能力来源 内核字段类型,开箱即用 k-NN 插件 + 索引级开关
索引级开关 无需,index 默认 true 必须 index.knn: true(建后不可改)
维度上限 dims ≤4096 dimension [1, 16000]
底层引擎 HNSW / 量化 / flat(由 index_options.type) lucene / faiss / nmslib(弃用)
默认量化 9.1+ 按维度自动选择(见 6.7) compression_level 1x~32x
过滤语义 knn query 内 filter = pre-filter;bool.filter = post-filter ANN 的 filter = 检索后过滤
许可 Elastic License 2.0 等 Apache-2.0(正文未核验)
最新稳定 9.5.6 3.9.0(2.x 维护 2.19.7)

1.3 适合 / 不适合(按子产品)

ES 适合:已有 ES 集群、需 BM25 + 稠密混合检索且要 RRF;已有完善的分片 / 副本 / 快照体系;数据量在搜索集群常规量级;需要 retriever.rrf、ES|QL 等查询语言能力。 ES 不适合:向量规模远超倒排数据、QPS 极高;需要 GPU / 专用分布式向量引擎;许可不接受 Elastic License 2.0 约束。

OpenSearch 适合:已在 OpenSearch / 兼容分支上、希望 Apache-2.0 生态;需要 faiss 的 IVF/PQ 或磁盘模式;维度可到 16000。 OpenSearch 不适合:无法接受 index.knn: true 建后不可改(需 reindex);依赖已弃用的 nmslib;需要开箱即用的 pre-filter(其 ANN filter 是检索后过滤)。

1.4 规模、链路位置与「何时该换」

项 经验区间(非官方承诺,须实测)
条数 与搜索集群同量级;向量与倒排同段,规模受分片与堆内存约束
维度 ES dims ≤4096;OpenSearch dimension ≤16000;常见 768 / 1024 / 1536
QPS 依赖分片数、num_candidates / k、堆内存,须压测
过滤比例 低命中率过滤对两者都是难点(见 6.5)

链路位置:离线「文档 → Embedding → 写入文档的一个向量字段(与正文、标量字段同文档)」;在线「query → Embedding → knn query(可叠加全文与 filter)→ 取回 _source → 重排 → LLM / 展示」。向量检索只是召回层的一个子句,最大价值是全文与向量在同一 DSL 内融合。

该换专用向量库的信号:向量规模 / QPS 远超搜索集群承载;低命中率过滤导致召回持续不达标;需要十亿级分布式向量优化或 GPU;向量检索要独立扩容而不想拖累搜索集群;需要内核级多向量 / 复杂重排。


2. 版本、许可与官方入口

2.1 版本状态表

产品 版本 时间 状态 备注
ES 9.5.6 2026-11-02 最新 同期维护 9.4.9、8.19.24
ES 9.2 官方未标注日期 已发布 ES|QL 引入 KNN()、FORK / FUSE(tech preview)
ES 9.1 官方未标注日期 已发布 默认量化策略变更(见 6.7)、RRF 多字段 query
OpenSearch 3.9.0 2026-09-29 Latest knn_vector 动态映射(默认关闭)
OpenSearch 2.19.7 官方未标注日期 2.x 维护分支 —

2.2 许可与官方入口(按子产品)

  • ES:Elastic License 2.0(默认),源码可选 SSPLv1 / AGPLv3;客户端为 Apache-2.0。Serverless 与部分量化默认策略受许可档位影响(见 6.7)。许可变更风险以 https://www.elastic.co/pricing/faq/licensing 为准。
  • OpenSearch:Apache-2.0(官方 LICENSE 正文未直接核验,以官方仓库为准)。
类型 Elasticsearch OpenSearch
文档入口 https://www.elastic.co/docs https://opensearch.org/docs
字段类型文档 https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/dense-vector https://opensearch.org/docs/latest/field-types/supported-field-types/knn-vector/
查询文档 https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-knn-query https://docs.opensearch.org/3.6/search-plugins/knn/approximate-knn
RRF / 混合 https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrievers/rrf-retriever 官方资料未提供
Releases https://github.com/elastic/elasticsearch/releases https://github.com/opensearch-project/OpenSearch/releases
官网 / 镜像仓库 / SDK / 控制台 官方资料未提供逐字 URL,勿臆测 官方资料未提供逐字 URL,勿臆测

2.3 版本识别命令

# 两者通用做法:查集群信息响应里的 version.number(端点与端口以实际部署 / 官方文档为准)
$ curl -s "http://<host>:<port>/" | grep -o '"number"[^,]*'

2.4 近两年重要变更与弃用提醒

ES:9.1 起 float 向量按维度自动量化(<384 维 int8_hnsw、≥384 维 bbq_hnsw);9.1+ RRF 支持多字段 query;9.2+ 子检索器 weight;9.2 ES|QL 引入 KNN() / FORK / FUSE(tech preview,GA 状态未核实);Serverless / 9.4+ 许可允许时默认 bbq_disk。

OpenSearch:nmslib 引擎已弃用,应选 lucene / faiss;3.9 提供 knn_vector 动态映射,需开 knn.dynamic_mapping.enabled(默认关闭,只建字段不启用 ANN)。

版本差异:改 dense_vector 的 index_options.type 不会重索引已有向量,已写入的段保持原索引形态;要让新策略作用于存量数据必须 reindex。 避坑:OpenSearch 的 settings.index.knn: true 在建索引后不可改,只能新建索引并 reindex 数据。


3. 安装与启动

3.1 说明与前置条件

本类产品通常已有集群,「安装」实为「在已有索引上启用向量能力」。官方资料未提供两者官方安装命令、镜像 tag 与端口,部署安装请以官方文档为准,勿臆测。

  • ES:dense_vector 为内核字段类型,无需额外插件;需确认版本 ≥8.x 且 dense_vector 可用。
  • OpenSearch:需 k-NN 插件可用;索引创建时就必须带 settings.index.knn: true,事后无法补。
  • 通用前置:JDK / 堆内存 / 分片规划沿用现有搜索集群基线(通用运维见根目录手册)。

3.2 ES:创建带 dense_vector 的索引

ES_HOST="http://<host>:<port>"   # 替换为实际集群地址
curl -s -X PUT "$ES_HOST/knn-demo" -H 'Content-Type: application/json' -d '{
  "mappings": {
    "properties": {
      "content":  { "type": "text" },
      "category": { "type": "keyword" },
      "vec": {
        "type": "dense_vector",
        "dims": 3,
        "index": true,
        "similarity": "cosine",
        "index_options": { "type": "hnsw", "m": 16, "ef_construction": 100 }
      }
    }
  }
}'

示例用 3 维,实际常见 768 / 1024 / 1536;dims ≤4096。以上参数均取自官方 dense-vector 映射文档。

3.3 OpenSearch:创建带 knn_vector 的索引

OS_HOST="http://<host>:<port>"   # 替换为实际集群地址
curl -s -X PUT "$OS_HOST/knn-demo" -H 'Content-Type: application/json' -d '{
  "settings": { "index.knn": true },
  "mappings": {
    "properties": {
      "content":  { "type": "text" },
      "category": { "type": "keyword" },
      "vec": { "type": "knn_vector", "dimension": 3 }
    }
  }
}'

示例用 3 维;dimension 上限 16000。引擎(lucene / faiss,勿用已弃用 nmslib)、space_type、data_type、mode、compression_level 的具体映射结构官方资料未给出逐字写法,按官方文档配置。

3.4 目录与端口表

项 ES OpenSearch 备注
HTTP 端口 通用默认 9200 通用默认 9200 官方资料未核实,以实际配置为准
向量字段 dense_vector knn_vector 无独立端口
数据 / 索引 Lucene 段(分片目录) Lucene 段(分片目录) 纳入集群快照
日志 集群日志目录 集群日志目录 无独立日志

3.5 健康检查与连通性验证

判定「向量能力就绪」的可靠方式:写入一条带向量的文档,随后执行 knn 检索能返回该文档。ES 用 5.1 的 knn query;OpenSearch 的 knn 查询体官方资料未提供逐字参数,按官方文档构造后验证。仅能建索引、不能 knn 检索,说明 ANN 未真正启用(OpenSearch 尤其要检查 index.knn: true 与动态映射开关)。

3.6 生产最小配置建议

认证 / TLS / RBAC / 网络暴露面沿用搜索集群基线(通用运维见根目录手册);堆内存与分片数需把向量索引纳入容量评估;索引级设置(尤其 OpenSearch 的 index.knn)建前定稿。

⚠️ 危险:对已有大索引直接改 dense_vector 映射参数或补 index.knn 不会作用于存量数据,误以为已生效会带来召回与容量双重事故。


4. 核心概念与数据模型

4.1 术语对照(按子产品)

通用术语 Elasticsearch OpenSearch
向量字段 dense_vector knn_vector
维度 dims(≤4096) dimension([1,16000])
相似度 / 空间 similarity space_type
元素类型 element_type data_type
索引形态 index_options.type 引擎 + mode / compression_level
TopK 近邻 knn query k-NN 查询
混合融合 retriever.rrf 官方资料未提供逐字条目
文档 / 索引 _doc / index _doc / index

4.2 横向对照表:字段 / 索引 / 过滤差异(第 4 章,重点)

维度 ES dense_vector OpenSearch knn_vector
字段类型名 dense_vector knn_vector
维度参数 / 上限 dims,≤4096 dimension,[1, 16000]
是否要索引开关 index 默认 true 索引级 settings.index.knn: true(建后不可改)
相似度 / 空间 l2_norm / dot_product / cosine(默认)/ max_inner_product l1 / l2 / linf / cosinesimil / innerproduct / hamming / hammingbit
元素类型 float / bfloat16 / byte / bit binary / byte / float / half_float
索引类型 hnsw / int8_hnsw / int4_hnsw / bbq_hnsw / flat / int8_flat / int4_flat / bbq_flat / bbq_disk lucene / faiss(HNSW + IVF + PQ)/ nmslib(已弃用)
建索引参数 m=16、ef_construction=100 mode(in_memory / on_disk)、compression_level(1x~32x)
量化入口 index_options.type compression_level + 引擎
过滤行为 knn query 内 filter = pre-filter;bool.filter = post-filter ANN 的 filter = 检索后过滤
动态映射 官方资料未提供 3.9 需 knn.dynamic_mapping.enabled(默认关闭,只建字段不启用 ANN)
IVF 训练 官方资料未提供 faiss IVF 需 Train API 训练模型

避坑:这张表是本篇最容易被旧教程误导的地方——ES 与 OpenSearch 的字段名、索引开关、过滤语义都不通用,把 ES 的 dense_vector 写法照搬到 OpenSearch(或反过来)会直接失败。

4.3 数据模型、距离与方向

两者都是「index → 文档 → 字段(正文 text + 标量 keyword + 向量字段)」,向量与倒排字段同文档,无独立 collection / load 步骤。

  • ES:similarity 默认 cosine;l2_norm 越小越相似,dot_product / cosine / max_inner_product 按分数越大越相似(查询侧以 _score 体现)。
  • OpenSearch:space_type 决定距离语义,如 l2 / l1 / linf 越小越相似,cosinesimil / innerproduct 越大越相似,hamming / hammingbit 用于二值。

4.4 索引参数表(按子产品)

产品 参数 默认值 作用
ES m 16 HNSW 每层连接数
ES ef_construction 100 建索引候选集
ES k — 返回条数,必须 ≤ num_candidates
ES num_candidates 1.5 × k,≤10000 每分片候选数,召回 / 延迟主旋钮
ES knn.filter — pre-filter,在 ANN 之前裁剪候选
ES similarity — 结果最低相似度阈值
ES query_vector_builder — 用模型在查询时生成向量(替代 query_vector)
OpenSearch dimension — [1,16000],建字段时定
OpenSearch mode — in_memory / on_disk
OpenSearch compression_level — 1x~32x 压缩
OpenSearch space_type — 距离空间
OpenSearch data_type — binary / byte / float / half_float

4.5 生命周期与一致性

写入文档后需经过索引 refresh 才可被检索(搜索集群通用行为);向量索引随 Lucene 段构建与合并,无「load 集合」步骤。一致性沿用各自集群的刷新 / 副本模型(近实时,非强一致事务),与 pgvector 的事务型语义不同。


5. 快速上手:完整 CRUD 示例

示例统一用 3 维向量便于阅读;实际常见 768 / 1024 / 1536 维。以下 REST 路径为通用形态示意,端点与端口以实际部署 / 官方文档为准。

5.1 Elasticsearch:完整 REST / cURL CRUD

ES_HOST="http://<host>:<port>"          # 替换为实际集群地址
IDX="knn-demo"

# 1) 建索引(若 3.2 已建可跳过)
curl -s -X PUT "$ES_HOST/$IDX" -H 'Content-Type: application/json' -d '{
  "mappings": { "properties": {
    "content":  { "type": "text" },
    "category": { "type": "keyword" },
    "vec": { "type": "dense_vector", "dims": 3, "index": true,
             "similarity": "cosine",
             "index_options": { "type": "hnsw", "m": 16, "ef_construction": 100 } }
  } }
}'

# 2) 插入文档
curl -s -X POST "$ES_HOST/$IDX/_doc/1" -H 'Content-Type: application/json' \
  -d '{"content":"向量检索入门","category":"tech","vec":[1,2,3]}'
curl -s -X POST "$ES_HOST/$IDX/_doc/2" -H 'Content-Type: application/json' \
  -d '{"content":"关系型数据库运维","category":"tech","vec":[4,5,6]}'
curl -s -X POST "$ES_HOST/$IDX/_doc/3" -H 'Content-Type: application/json' \
  -d '{"content":"咖啡拉花教程","category":"life","vec":[7,1,2]}'
curl -s -X POST "$ES_HOST/$IDX/_refresh"

# 3) knn 相似度检索
curl -s -X POST "$ES_HOST/$IDX/_search" -H 'Content-Type: application/json' -d '{
  "knn": { "field": "vec", "query_vector": [3,1,2], "k": 3, "num_candidates": 100 },
  "_source": ["content", "category"]
}'

# 4) 带标量过滤的检索:pre-filter 必须放在 knn 对象的 filter 里
curl -s -X POST "$ES_HOST/$IDX/_search" -H 'Content-Type: application/json' -d '{
  "knn": { "field": "vec", "query_vector": [3,1,2], "k": 3,
           "num_candidates": 100,
           "filter": { "term": { "category": "tech" } } },
  "_source": ["content", "category"]
}'

# 5) 更新  6) 删除  7) 清理
curl -s -X POST "$ES_HOST/$IDX/_doc/1" -H 'Content-Type: application/json' \
  -d '{"content":"向量检索入门(修订)","category":"tech","vec":[1,2,4]}'
curl -s -X DELETE "$ES_HOST/$IDX/_doc/3"
curl -s -X DELETE "$ES_HOST/$IDX"

filter 内的 term 为 ES 标准查询子句(通用 DSL,具体写法以官方文档为准);关键点不是子句写法,而是 filter 必须位于 knn 对象内部。

5.2 输出怎么读

字段 含义
hits.hits[]._id 文档 id,用于回表取原文
hits.hits[]._score 相似度得分(默认 cosine 下越大越相似),不是距离
hits.hits[]._source 正文与标量字段,验证过滤是否生效
hits.total 命中总数,用来发现「过滤后结果变少」

5.3 OpenSearch:可运行的建索引与写入

OS_HOST="http://<host>:<port>"          # 替换为实际集群地址
IDX="knn-demo"

curl -s -X PUT "$OS_HOST/$IDX" -H 'Content-Type: application/json' -d '{
  "settings": { "index.knn": true },
  "mappings": { "properties": {
    "content":  { "type": "text" },
    "category": { "type": "keyword" },
    "vec": { "type": "knn_vector", "dimension": 3 }
  } }
}'
curl -s -X POST "$OS_HOST/$IDX/_doc/1" -H 'Content-Type: application/json' \
  -d '{"content":"向量检索入门","category":"tech","vec":[1,2,3]}'
curl -s -X POST "$OS_HOST/$IDX/_doc/2" -H 'Content-Type: application/json' \
  -d '{"content":"关系型数据库运维","category":"tech","vec":[4,5,6]}'
curl -s -X POST "$OS_HOST/$IDX/_doc/3" -H 'Content-Type: application/json' \
  -d '{"content":"咖啡拉花教程","category":"life","vec":[7,1,2]}'
curl -s -X DELETE "$OS_HOST/$IDX/_doc/3"      # 删除
curl -s -X DELETE "$OS_HOST/$IDX"              # 清理

避坑:OpenSearch 的 knn 查询体逐字参数名官方资料未核实,故此处不臆造查询 DSL;请按 https://docs.opensearch.org/3.6/search-plugins/knn/approximate-knn 构造 knn 查询后再做「写入一条 → knn 检索返回」的就绪验证。可以确认的行为是:ANN 索引的 filter 是检索后过滤(4.2 表),低命中率过滤会明显少结果。

5.4 旧教程会怎么写

避坑:ES 旧教程常把过滤写成 bool.filter / post_filter,并当成「pre-filter」。这是 post-filter:ANN 先取 TopK 再过滤,可能返回少于 k 条。正确写法是把 filter 放进 knn query 对象内部(5.1 第 4 步)。 避坑:OpenSearch 旧教程用 nmslib 引擎、或建索引时漏掉 index.knn: true 事后想补——前者已弃用(改 lucene / faiss),后者建后不可改,只能新建索引 + reindex。


6. 索引与检索进阶

6.1 索引参数调优(按子产品)

产品 参数 默认值 影响 建议(经验值,实测为准)
ES num_candidates 1.5 × k,≤10000 每分片候选↑ → 召回↑、延迟↑ 从 10×k 内逐步压测
ES k — 返回条数,须 ≤ num_candidates 按业务 TopK 定
ES m / ef_construction 16 / 100 图质量与体积 建索引期参数,改需 reindex
ES similarity — 最低分阈值 用于截断低质结果
OpenSearch compression_level — 1x~32x,压缩↑ 召回↓ 按内存预算选
OpenSearch mode — in_memory / on_disk 大容量用 on_disk

6.2 横向对照表:索引 / 量化 / 过滤 / 混合(第 6 章)

维度 Elasticsearch OpenSearch
ANN 索引族 index_options.type 九种(hnsw / int8_hnsw / int4_hnsw / bbq_hnsw / flat / int8_flat / int4_flat / bbq_flat / bbq_disk) lucene / faiss(HNSW + IVF + PQ)/ nmslib(弃用)
默认量化 9.1+:<384 维 int8_hnsw、≥384 维 bbq_hnsw;Serverless / 9.4+ 许可允许时 bbq_disk compression_level 手动 1x~32x
改索引类型的效果 不会重索引已有向量,须 reindex 引擎在建索引时选定
过滤语义 knn filter = pre-filter;bool.filter = post-filter filter = 检索后过滤
混合检索 retriever.rrf(retrievers≥2、rank_constant=60、rank_window_size=10、filter) 官方资料未提供逐字条目
RRF 限制 不支持 scroll / sort / rescore 官方资料未提供
稀疏 / 多向量 官方资料未提供逐字条目 faiss IVF 需 Train API

6.3 recall 与延迟取舍

num_candidates(ES)与候选 / 压缩档位(OpenSearch)是主要旋钮:候选越大召回越高、延迟与 CPU 越高。方法(经验):用 flat / 精确检索跑 ground truth,再对同一批 query 算 recall@k,逐步加候选到达标。

6.4 标量过滤:pre-filter 还是 post-filter(重点)

产品 写法 行为 后果
ES knn 对象内 filter pre-filter,先裁剪候选再做 ANN 结果完整、性能更好
ES bool.filter / post_filter post-filter,ANN 取 TopK 后再过滤 可能返回少于 k 条
OpenSearch ANN 查询的 filter 检索后过滤 低命中率时明显少结果

避坑:「过滤结果变少」不要先怀疑数据没写进去,先看过滤子句放在哪一层。ES 一律用 knn query 的 filter;OpenSearch 需接受检索后过滤的语义,必要时改用引擎侧过滤能力或加大候选量(以官方文档为准)。

6.5 混合检索:ES retriever.rrf 参数与限制

retriever.rrf 用于把多个检索器(BM25 全文 + knn 稠密等)融合:

参数 默认值 说明
retrievers 必须 ≥2 子检索器数组,具体类型以官方文档为准
rank_constant 60 RRF 公式的秩常数
rank_window_size 10 每个子检索器参与融合的窗口
filter — 作用于检索器的过滤

版本演进:9.1+ 支持多字段 query;9.2+ 子检索器支持 weight。限制:不支持 scroll、sort、rescore。

子检索器的逐字类型名官方资料未核实,故此处只给参数与限制、不给臆造的完整 JSON;retrievers 内具体写法以官方 RRF retriever 文档为准。

6.6 量化与压缩(重点)

ES 9.1+ 默认量化策略:Stack 9.1 起,float 向量 <384 维默认 int8_hnsw、≥384 维默认 bbq_hnsw;Serverless / 9.4+ 在许可允许时默认 bbq_disk。这意味着即使你没显式写 index_options.type,索引形态也已由维度决定。可用 element_type(float / bfloat16 / byte / bit)与 index_options.type(hnsw / int8_hnsw / int4_hnsw / bbq_hnsw / flat / int8_flat / int4_flat / bbq_flat / bbq_disk)显式覆盖。

避坑:改 index_options.type 不会重索引已有向量。已写入的 Lucene 段保持旧索引形态,只有新写入 / 新段才用新策略;要让存量向量生效必须 reindex。

OpenSearch:compression_level 1x~32x 配合 faiss PQ;data_type(binary / byte / float / half_float)与 mode(in_memory / on_disk)控制精度与内存。

6.7 容量估算(经验公式,非官方承诺)

向量原始体积 ≈ 4 × dim 字节/向量(float32);dim=768、100 万条 ≈ 3.07 GB(未计副本与段开销)
含副本总量 ≈ 原始体积 × (1 + 副本数)
HNSW / 量化索引额外开销随 m、量化档位与段合并波动,须按集群实测
ES num_candidates 与 OpenSearch 候选量主要影响查询期 CPU / 堆内存,不影响存储

系数为经验区间,非官方承诺;用集群监控实测后做容量规划。


7. 生产部署与运维

7.1 高可用、备份与监控(按子产品)

  • ES:向量索引随分片 / 副本复制;快照(snapshot)备份含向量段,恢复后无需单独重建索引;监控沿用集群指标,重点看查询延迟、num_candidates 相关 CPU、堆内存与段合并。
  • OpenSearch:同样随分片 / 副本复制与快照备份;需额外监控 k-NN 插件的图 / 缓存内存、index.knn 是否生效、faiss IVF 模型是否已 Train。
指标 关注点 告警阈值(经验值)
向量查询 P99 延迟 候选量是否过大 相对基线翻倍即排查
堆内存 / 段合并 向量索引占用 超水位即扩容
过滤后命中数 是否 post-filter 截断 明显少于 k 即排查过滤位置
副本延迟 / 分片健康 向量段复制 沿用集群基线

7.2 升级、迁移与安全

  • 升级:ES 跨 9.x 升级前核对默认量化策略变化(9.1+);改 index_options.type 后要 reindex 存量。OpenSearch 升级时确认 nmslib 已弃用,迁移到 lucene / faiss;index.knn 开关只能在新建索引时决定。
  • 容量与扩缩容:按 6.7 估算并预留副本与段合并空间;扩分片需重建索引(reindex),属计划内变更。
  • 安全基线:认证、TLS、RBAC、网络暴露面沿用集群基线;向量字段同样受字段级 / 文档级安全控制(通用运维见根目录手册)。
  • 日志:集群日志目录,k-NN 插件无独立日志文件。

⚠️ 危险:对生产索引执行 reindex / 删除重建会改变索引名与别名指向,务必先切别名、保留旧索引回滚能力。


8. 高频故障与排障

症状 可能原因 定位命令 处置
[ES] dense_vector 映射报错 / dims 不符 dims 超 4096 或写入向量维度不匹配 GET /<index>/_mapping 对齐 dims 与写入维度
[ES] 过滤后结果少于 k 用了 bool.filter / post_filter(post-filter) 检查查询体过滤子句位置 改用 knn query 内的 filter
[ES] 改 index_options.type 后召回没变 新策略不重索引已有向量 GET /<index>/_mapping + 段信息 reindex 存量数据
[ES] knn 报错 k > num_candidates k 超过候选数 检查查询体 k / num_candidates 保证 k ≤ num_candidates(≤10000)
[ES] 查询慢 / CPU 高 num_candidates 过大 集群慢日志 / 监控 下调候选量、加副本分摊
[OS] knn 查询不返回 / ANN 未启用 建索引时漏 index.knn: true 或动态映射默认关闭 GET /<index>/_settings 新建带 index.knn: true 的索引并 reindex
[OS] 提示 nmslib 相关告警 引擎已弃用 GET /<index>/_mapping 改用 lucene / faiss
[OS] 过滤后结果明显变少 ANN filter 是检索后过滤 对比无过滤 knn 结果 加大候选量或调整过滤策略(以官方文档为准)
[OS] dimension 超限 超过 16000 GET /<index>/_mapping 降维或改用更小维度
[通用] 连不上 / 写入失败 集群不可达、分片未分配、磁盘满 集群健康 / 分配接口(以官方文档为准) 恢复节点、清理磁盘、检查分片
[通用] 版本升级后 knn 报错 查询 DSL / 默认量化策略版本差异 查 version.number 按新版本文档调整查询体与索引策略
[通用] OOM / 堆内存溢出 向量索引 + 候选量叠加 集群监控 / 日志 加堆内存、降候选、用量化或 on_disk

9. 常见坑与避坑清单

  1. 现象:ES 过滤后结果变少。原因:bool.filter 是 post-filter。怎么做:pre-filter 必须用 knn query 的 filter。
  2. 现象:ES 改了 index_options.type 却没效果。原因:不会重索引已有向量。怎么做:reindex 存量数据。
  3. 现象:ES 没写 index_options.type,索引形态却不是预期。原因:9.1+ 按维度默认量化(<384 int8_hnsw、≥384 bbq_hnsw)。怎么做:显式写 index_options.type 并核对维度阈值。
  4. 现象:ES knn 报 k > num_candidates。原因:k 必须 ≤ num_candidates(≤10000,默认 1.5×k)。怎么做:调大 num_candidates 或减小 k。
  5. 现象:ES RRF 查询加 sort / scroll 报错。原因:retriever.rrf 不支持 scroll / sort / rescore。怎么做:改走普通查询或调整融合结构。
  6. 现象:ES 9.2 ES|QL 的 KNN() / FORK / FUSE 当成 GA 写进方案。原因:tech preview,GA 版本未核实。怎么做:标注「以官方文档为准」,勿写成稳定能力。
  7. 现象:OpenSearch 建索引时漏 index.knn: true,事后想补。原因:建后不可改。怎么做:新建索引 + reindex。
  8. 现象:OpenSearch 用了 nmslib。原因:引擎已弃用。怎么做:选 lucene / faiss。
  9. 现象:OpenSearch 过滤后结果明显变少。原因:ANN filter 是检索后过滤。怎么做:加大候选量并接受语义差异,勿按 pre-filter 预期验收。
  10. 现象:OpenSearch 动态映射建了 knn_vector 字段却不做 ANN。原因:knn.dynamic_mapping.enabled 默认关闭,只建字段不启用 ANN。怎么做:显式开启并核对索引设置。
  11. 现象:把 ES 的 dense_vector 写法照搬到 OpenSearch(或反之)。原因:字段名、维度参数、索引开关、过滤语义都不通用。怎么做:按 4.2 对照表逐项区分。
  12. 现象:reindex / 删索引重建后应用查不到数据。原因:别名未切换、索引名变化。怎么做:⚠️ 先切别名并保留旧索引回滚,这是可能导致线上事故的操作。

10. 速查表(横向对照)

操作 Elasticsearch OpenSearch 说明
字段类型 "type": "dense_vector" "type": "knn_vector" 名称不通用
维度参数 "dims": 3(≤4096) "dimension": 3(≤16000) 示例 3 维
相似度 / 空间 "similarity": "cosine" space_type(l2 / cosinesimil / …) 默认 cosine(ES)
元素类型 "element_type": "float" data_type(float / byte / …) 量化入口
索引形态 "index_options": {"type":"hnsw","m":16,"ef_construction":100} 引擎 lucene / faiss + mode / compression_level 勿用 nmslib
索引开关 index 默认 true settings.index.knn: true ⚠️ OS 建后不可改
建索引 PUT /<index> PUT /<index> 建前定稿设置
写文档 POST /<index>/_doc/1 POST /<index>/_doc/1 向量放字段里
刷新 POST /<index>/_refresh 集群通用 refresh 写入后可检索
knn 检索 {"knn":{"field":"vec","query_vector":[3,1,2],"k":3,"num_candidates":100}} 查询体以官方文档为准 官方资料未给 OS 逐字参数
pre-filter knn 对象内 "filter" 无(filter 为检索后过滤) ES 必用此写法
候选量 num_candidates(默认 1.5×k,≤10000) 引擎侧候选 / compression_level 召回 / 延迟旋钮
查询向量生成 query_vector_builder 官方资料未提供 ES 可查询时生成
相似度阈值 knn similarity 官方资料未提供 截断低质结果
显式量化类型 int8_hnsw / bbq_hnsw / bbq_disk 等九种 compression_level 1x~32x 9.1+ 有默认策略
混合检索 retriever.rrf(rank_constant 60、rank_window_size 10) 官方资料未提供 不支持 scroll / sort / rescore
ES|QL 9.2 KNN() / FORK / FUSE(tech preview) — GA 状态未核实
IVF 训练 官方资料未提供 faiss IVF 需 Train API 建模前置
更新 / 删除 POST /<index>/_doc/1、DELETE /<index>/_doc/1 同左(通用 REST) —
清索引 DELETE /<index> DELETE /<index> ⚠️ 高危,先切别名
端口 / 路径 值 备注
HTTP 端口 通用默认 9200(两者) 官方资料未核实,以实际配置为准
向量字段 dense_vector / knn_vector 无独立向量服务端口
数据 / 索引 Lucene 段(分片目录) 纳入集群快照
日志 集群日志目录 无独立日志

11. 参考与延伸

官方链接清单

资源 URL
ES 文档入口 https://www.elastic.co/docs
ES dense_vector 映射 https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/dense-vector
ES knn query https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-knn-query
ES RRF retriever https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrievers/rrf-retriever
ES 许可 FAQ https://www.elastic.co/pricing/faq/licensing
ES Releases https://github.com/elastic/elasticsearch/releases
OpenSearch 文档入口 https://opensearch.org/docs
OpenSearch knn_vector 字段 https://opensearch.org/docs/latest/field-types/supported-field-types/knn-vector/
OpenSearch approximate-knn https://docs.opensearch.org/3.6/search-plugins/knn/approximate-knn
OpenSearch Releases https://github.com/opensearch-project/OpenSearch/releases

与同册其他产品的关系:已有 ES / OpenSearch → 本篇;已有 PG → pgvector.md;已有 Redis → Redis-Vector-Search.md;已有 ClickHouse → ClickHouse.md;已有国产关系库 → 国产数据库向量能力.md;需分布式专用向量库 → 01-专用向量数据库 分册。

进阶阅读:ES dense_vector 的 index_options 与量化档位、RRF retriever 限制;OpenSearch k-NN 插件的引擎差异、faiss IVF Train API、3.9 动态映射。

本篇「未核实 / 以官方为准」事项:

  1. ES 9.2 ES|QL KNN() / FORK / FUSE 为 tech preview,GA 版本未核实,正文不得写成稳定能力。
  2. OpenSearch Apache-2.0 官方 LICENSE 正文未直接核验,以官方仓库为准。
  3. OpenSearch knn 查询 DSL 的逐字参数名未核实,故 5.3 / 6.5 未给臆造查询体,按官方文档构造。
  4. ES RRF 子检索器的逐字类型名未核实;retrievers 内具体写法以官方文档为准。
  5. ES 9.1 / 9.2 / 9.4+ 的具体发布日期未核实(官方资料仅给 9.5.6 日期)。
  6. 两者官网 / 镜像仓库 / SDK / 控制台 URL、安装命令、镜像 tag、HTTP 端口均官方资料未提供,勿臆测。
  7. 4.3 中相似度 / 距离方向的逐值口径、6.7 容量公式、各告警阈值均为经验性表述,非官方承诺,须实测。
  8. ES 9.4+ / Serverless 默认 bbq_disk 的「许可允许」具体条件未核实,以官方许可文档为准。
Elasticsearch / OpenSearch 向量检索手册 - 知识库 - 起航社区