亚马逊AWS官方博客

从自建 Elasticsearch 迁移到 Amazon OpenSearch Service 实践(三):查询兼容性验证与 BBoss 应用适配

摘要:本篇先基于实测给出查询兼容性总览与 k-NN 查询的具体改写方式,再介绍如何通过 BBoss Elasticsearch 框架的多数据源能力与 DSL 模板隔离,将应用层改动降到最低。


一、引言

本文是”从自建 Elasticsearch 迁移到 Amazon OpenSearch Service 实践”系列的第三篇,也是收官篇。系列共三篇:(一)数据迁移与同步(二)向量索引迁移与 Amazon Bedrock 集成;(三)查询兼容性验证与 BBoss 应用适配。前两篇已完成数据迁移与向量索引迁移,本篇聚焦最后一个挑战——查询兼容性,并介绍如何借助 BBoss 框架以最小改动完成应用层切换。

二、背景回顾

本系列第一篇《数据迁移与同步》第二篇《向量索引迁移与 Amazon Bedrock 集成》已分别解决了存量与增量数据迁移、向量索引迁移与 Embedding 模型切换两个挑战。迁移的最后一道关卡是查询兼容性:自建 Elasticsearch(以下简称 ES)8.x 的查询语句迁移到 Amazon OpenSearch Service(以下简称 AOS)3.x 后,哪些能零改动直接运行、哪些需要改写,以及应用层如何在不大幅改动业务代码的前提下完成切换。

本篇先基于实测给出查询兼容性总览与 k-NN 查询的具体改写方式,再介绍如何通过 BBoss Elasticsearch 框架的多数据源能力与 DSL 模板隔离,将应用层改动降到最低。

三、查询兼容性与改写

3.1 兼容性总览

基于实测验证,ES 8.x 到 AOS 3.x 的查询兼容性如下:

类别 改动情况 涉及查询类型
完全兼容(零改动) 无需修改 painless 脚本排序、function_score、multi_match、highlight (fvh/plain)、term/terms/range/bool/search_after、聚合
k-NN 查询结构改写 需改写 k-NN 向量搜索语法(字段路径、参数名变化)
Neural Search 替换 需改写 query_vector_builder → Neural Search (ML Commons)
date_nanos sort 小调整 去掉 format/numeric_type 参数
SQL endpoint 路径变化 _sql → _plugins/_sql

结论:大部分查询(普通搜索、聚合、脚本排序等)完全零改动。需要改写的集中在 k-NN 向量搜索部分,属于语法结构变化而非逻辑变化。

3.2 k-NN 查询改写详解

k-NN 是 ES 到 OpenSearch 迁移中最大的语法差异:

ES 8.17

{
  "knn": {
    "field": "content_vector",
    "query_vector": [1.0, 2.0, "..."],
    "k": 10,
    "similarity": 0.8,
    "num_candidates": 1000
  }

3.2.2 Amazon OpenSearch Service

{
  "size": 10,
  "query": {
    "knn": {
      "content_vector": {
        "vector": [1.0, 2.0, "..."],
        "min_score": 0.8
      }
    }
  }
}

改写要点:

  • "field": "xxx"→ 字段名作为 k-NN 对象的 key
  • query_vectorvector
  • similaritymin_score,返回数量由外层 size 控制
  • num_candidates → 删除(可选 method_parameters.ef_search
  • min_scorek 不能共存,只能选其一

3.3 Mapping 改写

ES 8.17 Amazon OpenSearch Service
dense_vector knn_vector
dims: 1024 dimension: 1024
similarity: "cosine" space_type: "cosinesimil"
无需额外设置 index.knn: true + method + engine: faiss

Amazon OpenSearch Service 的 Mapping 示例:

{
  "settings": { "index.knn": true },
  "mappings": {
    "properties": {
      "title_vector": {
        "type": "knn_vector",
        "dimension": 1024,
        "method": {
          "name": "hnsw",
          "engine": "faiss",
          "space_type": "cosinesimil",
          "parameters": { "ef_construction": 128, "m": 24 }
        }
      }
    }
  }
}

两端建索引脚本(含 Mapping 差异对比)参考:create_indices.sh

k-NN 改写后迁移前后向量搜索的精度差异(HNSW 图结构差异导致的 Top-K 微小变化)已在本系列第二篇《向量索引迁移与 Amazon Bedrock 集成》给出实测数据与评估建议,本篇不再重复。

四、BBoss 应用层适配

4.1 为什么选择 BBoss

在迁移过渡期,应用需要同时连接 ES 和 Amazon OpenSearch Service 两个集群,进行对比验证后再切换。BBoss Elasticsearch 框架原生支持多数据源配置,且通过 XML DSL 模板管理查询语句,能够将 ES 和 OpenSearch 的查询语法差异隔离在模板层,应用代码无需修改。这意味着即使有多个查询模板,应用层的代码改动也仅限于新增一份 AOS 的 DSL 模板文件,业务逻辑代码不需要任何修改。

4.2 多数据源配置

BBoss 通过 application.properties 中的后缀区分不同数据源:

# ===== 数据源 1: ES 8.17 (default) =====
spring.elasticsearch.bboss.elasticsearch.rest.hostNames=http://<es-host>:9200
spring.elasticsearch.bboss.elasticsearch.dateFormat=yyyy.MM.dd
spring.elasticsearch.bboss.elasticsearch.timeZone=Asia/Shanghai
spring.elasticsearch.bboss.http.timeoutConnection=5000
spring.elasticsearch.bboss.http.timeoutSocket=50000
# ===== 数据源 2: Amazon OpenSearch Service =====
spring.elasticsearch.bboss.elasticsearch.rest.hostNames.aos=https://<aos-endpoint>:443
spring.elasticsearch.bboss.elasticsearch.rest.user.aos=${AOS_USER}
spring.elasticsearch.bboss.elasticsearch.rest.password.aos=${AOS_PASSWORD}
spring.elasticsearch.bboss.elasticsearch.dateFormat.aos=yyyy.MM.dd
spring.elasticsearch.bboss.elasticsearch.timeZone.aos=Asia/Shanghai
spring.elasticsearch.bboss.http.timeoutConnection.aos=5000
spring.elasticsearch.bboss.http.timeoutSocket.aos=50000

hostnameVerifier 留空表示跳过 hostname 验证,适用于 Amazon OpenSearch Service 的 VPC Endpoint 场景。

完整配置文件参考:application.properties.example

4.3 DSL 模板隔离查询差异

Boss 使用 XML 文件管理查询 DSL,为 ES 和 OpenSearch 分别维护模板文件。以 k-NN 查询为例,两端的差异完全封装在模板中:

query_dsl.xml(ES 8.17)

<property name="knnSearch"><![CDATA[{
    "query": {"knn": {
        "field": "title_vector",
        "query_vector": #[vector,serialJson=true],
        "k": #[k,datatype=int,defaultvalue=50],
        "num_candidates": 100
    }}
}]]></property>

os_query_dsl.xml(Amazon OpenSearch Service)

<property name="knnSearch"><![CDATA[{
    "query": {"knn": {
        "field": "title_vector",
        "query_vector": #[vector,serialJson=true],
        "k": #[k,datatype=int,defaultvalue=50],
        "num_candidates": 100
    }}
}]]></property>

ES 与 AOS 的完整 DSL 模板对比请参考:search-es.xml vs search-aos.xml

4.4 应用代码中切换数据源

@Service
public class SearchService {
    @Autowired
    private BBossESStarter bbossESStarter;
    // 查询 ES 8.17
    public String searchFromES(String index, String dslName, Map<String, Object> params) {
        ClientInterface client = bbossESStarter.getConfigRestClient("query_dsl.xml");
        return client.executeRequest(index + "/_search", dslName, params);
    }
    // 查询 Amazon OpenSearch Service
    public String searchFromAOS(String index, String dslName, Map<String, Object> params) {
        ClientInterface client = bbossESStarter.getConfigRestClient("aos", "os_query_dsl.xml");
        return client.executeRequest(index + "/_search", dslName, params);
    }
}

通过这种方式,迁移过渡期可以同时调用两个集群进行结果对比,验证通过后只需修改数据源名称即可完成切换。

五、查询兼容性验证

5.1 普通查询:完全兼容,零改动

测试项 ES 8.17 结果 AOS 3.3 结果 结论
multi_match 全文搜索 100 hits 100 hits ✅ 完全一致
painless 脚本排序 top sort: 36055.5 top sort: 36055.5 ✅ 完全一致,0% 差异
function_score + field_value_factor 完全一致 完全一致 ✅ 0% 差异
FVH / plain highlight 正常高亮 正常高亮 ✅ 完全一致
bool + range + term 组合 完全一致 完全一致 ✅ 零改动
聚合 (terms aggs) 5 buckets 5 buckets ✅ 完全一致
date_nanos 排序 102 hits 102 hits ✅ 去掉 format/numeric_type 即可
search_after 分页 正常 正常 ✅ 零改动

结论:在本次实验中,所有普通查询(非 k-NN)在 AOS 3.3 上完全兼容,查询结果 100% 一致,无需任何代码修改。实际操作中,建议以自身代码测试为准。

补充验证:基于 OpenSearch Benchmark 标准数据集(big5, CloudWatch Logs 格式, 1.16 亿文档)额外测试了 18 种查询场景(全文搜索、bool 组合、聚合、date_histogram、function_score、wildcard、prefix、exists、cross_fields multi_match、search_after 分页、_source 过滤、cardinality 去重等),结果均与 ES 完全一致。结合业务搜索场景的 8 种查询模板(painless 脚本排序、FVH highlight、date_nanos 排序、多级聚合等),共计 26 种查询场景全部兼容。

完整的 BBoss 双数据源代码示例(含 ES/AOS 查询模板对比)请参考:BBoss Java 代码示例

5.2 k-NN 向量搜索:需要业务评估

k-NN向量搜索是唯一需要改写并做业务评估的查询类别。改写方式见本文第二节,迁移前后的精度差异与评估建议见本系列第二篇。简言之:当文档间相似度区分度大时(如真实 Embedding 数据),Top-K 结果高度一致;当大量文档相似度接近时,Top-K 可能存在排列差异,但分数差异通常控制在 1% 以内。建议使用业务真实数据回归测试,关注 Top-K 对业务指标的实际影响,必要时调整 ef_search 参数。

六、系列总结

本系列以一个典型的企业搜索迁移场景为例,完整介绍了从自建 Elasticsearch 8.17 迁移到 Amazon OpenSearch Service 的实践方案:

  • 第一篇 通过 Migration Assistant (RFS) 支撑 TB 级存量数据高吞吐搬运、Logstash 多 pipeline 实现增量同步,并以逐索引比对确认数据零损耗;
  • 第二篇 给出向量索引迁移的三种策略,并以 Amazon Bedrock Titan Text Embeddings V2 为例,介绍应用端调用与 Neural Search 两种集成方式及 Embedding 模型的平滑切换;
  • 第三篇 基于实测确认大部分查询无需改动即可在 Amazon OpenSearch Service 上运行,需要改写的集中在 k-NN 向量搜索,并通过 BBoss 框架的多数据源能力与 DSL 模板隔离,将应用层改动降到最低。

实测验证表明,多个生产查询模板中大部分无需任何改动即可在 Amazon OpenSearch Service 上运行,k-NN 向量搜索的分数差异控制在 1% 以内。读者可以基于本系列方案,结合 AWS Migration Assistant 实现 TB 级数据的高吞吐迁移,或利用 Amazon OpenSearch Service 的 Neural Search 能力构建端到端的语义搜索管道。

➡️ 下一步行动:

相关产品:

相关文章:

七、相关链接

*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。

本篇作者

马佳

亚马逊云科技解决方案架构师,负责基于亚马逊云科技云平台解决方案的设计和咨询,亚马逊云科技人工智能机器学习领域成员。在机器学习、深度学习及自动驾驶感知领域,拥有丰富的理论及算法实践工程经验。

苏志勇

亚马逊云科技迁移解决方案架构师,主要负责企业上云跨云迁移相关的技术支持工作。曾担任研发工程师、解决方案架构师等职位,在 IT 专业服务和企业应用架构方面拥有多年的实践经验。

邢悦

亚马逊云科技迁移解决方案架构师,主要负责企业上云跨云迁移相关的技术支持工作。在制造、保险、物流等行业拥有10多年的研发和架构设计经验。


AWS 架构师中心:云端创新的引领者

探索 AWS 架构师中心,获取经实战验证的最佳实践与架构指南,助您高效构建安全、可靠的云上应用