暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Elaticsearch 向量迁 Easysearch:别只改字段名


Elasticsearch 向量迁 Easysearch:别只改字段名

最近好几拨朋友问同一件事:ES 上的向量检索,迁到 Easysearch 能不能直接用?

Easysearch 向量搜索 vs Elasticsearch:别再问"兼容不兼容"了,先看这篇

我的短答案是:向量数据能迁,API 和索引算法不能照搬。

稠密浮点向量换个字段类型就能灌进去;int8_hnsw
、pre-filter kNN、加权稀疏向量,这三样在 Easysearch 里没有一一对应的原样平替。能力有对应实现,但字段名、索引模型、过滤语义、稀疏语义都不等价。

下面按 Easysearch 2.3.1 实测口径,把该改什么、别踩什么一次说清楚。

1、先泼一盆冷水:不是改个字段名就完事

很多人看到官方迁移指南里写着:

dense_vector
 → knn_dense_float_vector
,数据保留

就以为「改 mapping 名,查询原样拷过去」。

跑起来你会发现:查询 DSL 变了,近似索引算法变了,带过滤条件时 TopK 还可能对不上。

2.3.1 这边,对 Easysearch 自有的稠密浮点向量和布尔稀疏向量,exact
、LSH、sparse_indexed
 查询都能工作。这句话的重点在「自有」——不是 ES 的 dense_vector
 / sparse_vector
 API 兼容层。

官方迁移指南「字段类型兼容性」章节写得很直白,向量这块必须装 knn 插件,目标索引先建好新 mapping,再灌数。

2、字段怎么换:dense_vector 对上的是 knn_dense_float_vector

对照关系先记死:

ES 类型
Easysearch 替代
数据能不能留
dense_vector
knn_dense_float_vector
能,数组格式兼容
knn_vector
(部分生态)
knn_dense_float_vector
sparse_vector
knn_sparse_bool_vector
数据形态不同,见后文

稠密向量的数据长这样,两边都能认:

[0.12-0.030.880.45]

ES 侧常见写法(示意):

PUT products
{
"mappings": {
    "properties": {
      "embedding": {
        "type""dense_vector",
        "dims"768,
        "index"true,
        "similarity""cosine",
        "index_options": {
          "type""int8_hnsw"   // ← ES 默认量化近似索引,Easysearch 没有
        }
      }
    }
  }
}

Easysearch 侧要改成:

PUT products
{
"mappings": {
    "properties": {
      "embedding": {
        "type""knn_dense_float_vector",   // ← 这里!字段类型换名
        "knn": {
          "dims"768,
          "model""lsh",                   // ← 近似用 LSH,不是 HNSW
          "similarity""cosine",
          "L"99,
          "k"1
        }
      }
    }
  }
}

几点实操提醒:

  • 必须安装 knn
     插件,否则向量查询起不来。
  • 数组格式兼容,Gateway Bulk 灌数时向量值一般不用二次编码。
  • Easysearch 还不支持 int8_hnsw
    。内存占用和召回曲线别拿 ES 量化 HNSW 的经验直接套。
  • 小数据、要对齐过滤结果时,mapping 可以只写 dims
    ,查询用 model: exact

字段类型细节见官方文档:向量字段类型(K-NN)


3、查询怎么改:从 knn 换成 knn_nearest_neighbors

ES 8 常见写法:

POST products/_search
{
  "knn": {
    "field""embedding",
    "query_vector": [0.12-0.030.88],
    "k"10,
    "num_candidates"100,
    "filter": {
      "term": { "category""tech" }   // ← ES 的 pre-filter
    }
  }
}

Easysearch 统一走 knn_nearest_neighbors

POST products/_search
{
"size"10,
"query": {
    "knn_nearest_neighbors": {
      "field""embedding",
      "vec": {
        "values": [0.12-0.030.88]   // ← 这里!查询向量放 values
      },
      "model""lsh",
      "similarity""cosine",
      "candidates"100                 // ← 类似 num_candidates,建议 size 的 5~10 倍
    }
  }
}

精确搜索把 model
 改成 exact
,不用配 candidates

"model""exact",
"similarity""cosine"

客户端、查询模板、网关改写规则都要动。别指望「只换集群地址」。

查询参数完整说明:k-NN 查询 API

4、最容易踩的坑:过滤语义不是一回事

这是向量迁移里最容易「看起来能跑、结果对不上」的地方。

ES 的 knn filter
 是 pre-filter:先在满足条件的文档集合里找最近邻,尽量保证返回满 k 条「既相似又过筛」的结果。

Easysearch 文档里,向量查询可以塞进 bool
,和 filter
 组合:

POST products/_search
{
"size"10,
"query": {
    "bool": {
      "must": [
        {
          "knn_nearest_neighbors": {
            "field""embedding",
            "vec": { "values": [0.12-0.030.88] },
            "model""lsh",
            "similarity""cosine",
            "candidates"100
          }
        }
      ],
      "filter": [
        { "term": { "category""tech" } }
      ]
    }
  }
}

大白话讲差别:

  • pre-filter:先缩小候选池,再在池子里找邻居。
  • post-filter:先找一堆邻居,再扔掉不符合条件的。过滤很严时,最终可能凑不满 k 条,排序也可能和 ES 不一致。

实测口径(2.3.1):LSH + bool filter 不等效于 ES pre-filter kNN。

替代思路:

场景
建议
数据量不大,结果必须对齐
用 model: exact
,再叠 bool filter;
语义上更接近「全量算分后再筛」,上线前用业务数据对拍 TopK
数据量大,能接受近似
继续 LSH,把 candidates
 调大,做召回重叠率,业务侧接受差异
强依赖 ES 式 pre-filter
目前只能找类似替代;官方也表态:pre-filter 与加权稀疏在 Easysearch 里只能找替代,今年会继续加强向量查询和与 ES8 的兼容

别把「能组合 filter」理解成「和 ES pre-filter 一样」。验收时一定要单独测「带过滤的 TopK」。

5、稀疏向量:名字像,语义差很远

这是第二个容易想当然的点。

ES 的 sparse_vector
(配合 ELSER / sparse_vector
 query)是 加权稀疏:token → weight,分数跟权重有关。

Easysearch 的 knn_sparse_bool_vector
 是 布尔稀疏

每个维度只有 true/false,内部只存为 true 的下标,相似度是 Jaccard / Hamming。

写入形态大概长这样:

{
  "features": [[0351288], 1000]
}

意思是:总维度 1000,其中下标 0、3、5、12、88 为 true。

查询示例:

    // 1. 创建索引 — model 用 lsh(或 exact)
    PUT /products_0712
    {
      "mappings": {
        "properties": {
          "features": {
            "type""knn_sparse_bool_vector",
            "knn": {
              "dims": 1000,
              "model""lsh",
              "similarity""jaccard",
              "L": 99,
              "k": 1
            }
          }
        }
      }
    }
    // 2. 写入文档(格式不变)
    POST /products_0712/_doc/1
    {
      "features": [[0, 3, 5, 12, 88], 1000]
    }
    // 3. 查询 — 此时可以用 lsh 加速
    POST /products_0712/_search
    {
      "query": {
        "knn_nearest_neighbors": {
          "field""features",
          "vec": [[0, 5, 12, 100, 456], 1000],
          "model""lsh",
          "similarity""jaccard",
          "candidates": 50
        }
      }
    }

    结论写死:

    • 正确的做法是先创建索引,定义 knn_sparse_bool_vector
       字段时,model
       必须使用 lsh
       或 exact
      ,绝不能写成 sparse_indexed
    • 然后写入文档,稀疏向量格式始终是 [[true的下标], 总维度]
    • 最后查询时,model
       也要和映射保持一致(这里用 lsh
      ),vec
       直接传数组,不需要 values
       包装。

    6、一张迁移决策表 + 验收清单

    6.1 迁不迁,先看你依赖什么

    你现在的依赖
    迁 Easysearch 怎么走
    只用稠密浮点 embedding
    可迁:换 knn_dense_float_vector
    ,改查询 DSL
    依赖 int8_hnsw
     省内存
    接受 LSH / exact 的内存与召回取舍,重新压测
    依赖 knn pre-filter 强一致
    LSH 不等效;小库试 exact + filter 并对拍;大库接受近似或改业务
    依赖加权 sparse_vector
     / ELSER
    不能等价迁,改方案
    ES 7.12+ / 8.x 快照直恢
    向量索引建议 Gateway 迁移;目标侧先建新 mapping 再灌数

    ES 7.0–7.11 快照窗口相对顺;7.12+ / 8.x 快照格式与 Easysearch 2.x 不兼容,走 INFINI Gateway 更稳。

    6.2 上线前至少做这五步验收

    1. 文档量一致(含向量字段非空文档数)。
    2. 无过滤 TopK 重叠率:同一批 query,看 ES vs Easysearch 的命中重叠。
    3. 带过滤 TopK 对拍:这是坑点,单独测,别和「无过滤」混在一起报喜。
    4. 延迟与内存:LSH 的 L
      /k
      /candidates
       要重新调,别抄 ES 的 num_candidates
    5. 核心业务链路压测:推荐、语义搜索、RAG 召回,用真实流量回放。

    小索引先跑通 mapping 和查询,再全量迁。这句话在向量场景比普通文本索引更重要——mapping 建错,整库重灌。

    7、向量迁的是数据,不是 API

    回到开头那句话:

    • 稠密向量:数据兼容,字段和查询要改。

    • 近似索引:HNSW/int8 换成 LSH/exact,重新调参。

    • 过滤:LSH 不等效 pre-filter,exact 更接近但仍要对拍。

    • 稀疏:布尔稀疏 ≠ 加权稀疏。

    Easysearch 2.3.1 上,自有稠密浮点和布尔稀疏的 exact / LSH / sparse_indexed 都能干活。迁移不是「功能有没有」,而是「语义等不等价」。把等价边界画清楚,迁移才不会在上线那天翻车。

    你现在的 ES 向量栈是 HNSW、int8 量化,还是 ELSER 稀疏?欢迎留言。


    Easysearch 向量检索实战——一个脚本跑通全链路

    LangChain + Easysearch + MiMo 大模型——从零构建企业级 RAG 向量检索系统

    Easysearch 向量搜索 vs Elasticsearch:别再问"兼容不兼容"了,先看这篇

    Easysearch 向量检索之从原理到实战

    文章转载自铭毅天下Elasticsearch,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论