milvus es

ES 与 Milvus 结合实现高效文档搜索的实战指南

原文链接

目录

  1. 背景介绍
  2. 场景与效果概述
  3. 架构对比与问题分析
  4. Milvus 向量搜索架构
  5. ES + Milvus 搜索架构
  6. 详细流程解析
  7. Milvus 搜索配置详解
  8. ES 搜索策略与 DSL 配置
  9. 结果合并与排序策略
  10. 总结与未来优化

1. 背景介绍

随着团队和公司的发展,积累了大量各类文档,如技术分享文档、接口设计文档、业务对接文档、教程、Changelog 等。文档数量的增加和用户数量的增长使得高效的文档搜索功能变得至关重要。高效的搜索功能能够帮助用户快速查找和定位所需内容,显著提升工作效率。

Elasticsearch(ES) 擅长关键词匹配,适用于基于关键词的全文搜索。然而,随着语义搜索需求的增加,ES 在处理同义词、近义词等语义相近的内容时表现欠佳。

Milvus 是一个高性能的向量数据库,具备强大的语义搜索能力,能够基于向量的相似性进行检索,弥补 ES 在语义搜索上的不足。

本博客介绍了如何结合使用 ES 和 Milvus,充分发挥它们各自的优势,实现高效且准确的文档搜索。


2. 场景与效果概述

当前场景

  • 文档数量:约 8 万篇文档。
  • 文档类型:技术分享、接口设计、业务对接、教程、Changelog 等。
  • 用户反馈
    • 仅使用 ES 时,无法有效搜索同义词、近义词或语义相近的词语,影响搜索质量。
    • 仅使用 Milvus 时,用户通过直接搜索代码、API 无法找到对应文档。

效果指标

  • 搜索点击率:约 65%。

3. 架构对比与问题分析

单独使用 ES 的问题

  • 语义搜索能力有限:无法有效处理同义词、近义词等语义相近的内容,导致搜索结果不准确。
  • 用户体验不佳:用户在搜索时可能找不到相关的文档,影响工作效率。

单独使用 Milvus 的问题

  • 关键词匹配不足:用户通过直接搜索代码、API 名称等关键词时,无法找到对应文档。
  • 非中文场景下的搜索不准确:在处理非中文内容时,搜索效果欠佳。

结合使用 ES + Milvus 的优势

  • ES 擅长关键词匹配:能够快速找到包含特定关键词的文档。
  • Milvus 擅长语义搜索:能够根据向量相似性找到语义相近的文档。
  • 互补优势:通过结合两者的能力,提升整体搜索效果和用户体验。

图片


4. Milvus 向量搜索架构

单独使用 Milvus 的搜索流程

  1. 用户请求:用户提交搜索关键词。
  2. 特征化处理:后端将关键词转换为向量(词嵌入)。
  3. 向量搜索:调用 Milvus 的向量搜索接口,获取相似文档。
  4. 自定义评分:根据文档类型(如标题、正文)给予不同权重。
  5. 返回结果:将处理后的搜索结果返回给用户。

自定义评分示例

  • 标题:权重系数为 2。
  • h2 类型标题:权重系数为 1.5。
  • 正文:权重系数为 1。

5. ES + Milvus 搜索架构

结合使用 ES + Milvus 的搜索流程

  1. 用户请求:用户提交搜索关键词。

  2. 特征化处理:后端将关键词转换为向量(词嵌入)。

  3. 检索阶段

    • Milvus 向量搜索:基于向量数据进行相似性搜索。
    • ES 全文检索:通过 DSL(Domain Specific Language)进行关键词匹配搜索。
  4. 数据召回阶段

    • 自定义评分调整:根据文档类型给予不同权重。
    • 结果合并与排序:归一化处理、去重、重新评分后排序。
  5. 返回结果:将整合后的搜索结果返回给用户。

架构图说明

  • 左部分:数据清洗与落库。
  • 右部分:用户搜索流程,重点关注检索与召回阶段。

6. 详细流程解析

用户提交查询阶段

  • 词嵌入处理:将用户的搜索关键词通过词嵌入模型转换为向量。
  • 生成 ES 搜索 DSL:根据搜索需求生成 ES 的搜索查询语句。

检索阶段

  • Milvus 向量搜索

    • 基于向量数据进行相似性搜索,获取相关文档。
  • ES 全文检索

    • 使用生成的 DSL 对文档进行关键词匹配搜索,获取相关文档。

数据召回阶段

  • 自定义评分调整

    • 根据文档类型(如标题、正文)给予不同的权重系数。
  • 合并结果

    • 对 Milvus 和 ES 的搜索结果进行归一化处理。
    • 去重处理,避免同一文档重复出现。
    • 重新计算分数,根据调整后的评分进行排序。
  • 关键词高亮

    • 对 ES 返回的结果进行关键词高亮显示,提升用户体验。

结果返回用户

  • 高亮显示:向量搜索结果不具备关键词高亮,需要通过 ES 的搜索结果进行实现。
  • 最终返回:将合并、排序后的搜索结果返回给用户。

7. Milvus 搜索配置详解

使用 Node.js SDK 调用 Milvus 搜索

以下是一个使用 Node.js SDK 调用 Milvus 搜索的示例代码:

await app.milvus.search({collection_name: collection, // 集合名称partition_names,             // 分区名称vector: text_embs,           // 向量数据params: { nprobe: 16 },      // 搜索精度相关参数metric_type: searchConfig.metric_type, // 度量方式limit: limit ?? searchConfig.limit,    // 查询数量timeout: searchConfig.timeout,         // 超时时间offset: 0,                              // 从第0条开始查询filter: filter ?? null,                 // 过滤条件
});

配置参数说明

  • collection_name:指定要搜索的 Milvus 集合。
  • partition_names:因为文档分为中、英、日三种语言,所以根据用户当前搜索的语言选择相应的分区。
  • vector:搜索向量数据,即用户输入的关键词经过词嵌入生成的向量。
  • params.nprobe:用于 IVF 检索类型,影响搜索精度和耗时。值越大,搜索精度越高,但耗时也增加。
  • metric_type:度量方式,常用的有 IP(内积)和 L2(欧氏距离)。
  • limit:每次查询返回的结果数量。
  • timeout:查询的超时时间。
  • filter:一些过滤条件,例如只搜索特定类型的文档。

向量搜索的策略

  • 分区存储:根据文档的语言(中、英、日)进行分区存储,提升搜索准确性。

  • 评分策略

    • Milvus 评分:对搜索结果进行归一化处理,根据分数进行调整。
    • ES 评分:通过自定义系数提升 ES 的搜索结果排名。

8. ES 搜索策略与 DSL 配置

Elasticsearch DSL 配置

ES 使用 DSL(Domain Specific Language)进行搜索配置,主要包括四部分:

  1. 标题搜索 DSL
  2. 正文搜索 DSL
  3. 代码块搜索 DSL
  4. 增强搜索 DSL

此外,还包括关键词高亮的 DSL 配置。

搜索关键字配置

  • matchmatch_phrase_prefix
    • 标题:主要使用 matchmatch_phrase_prefix。由于标题字符较少,配置 minimum_should_match: '80%',允许拆词后命中 80%。同时配置 slop: 2,允许 2 个词的偏移。
  • match_phrase
    • 正文:仅配置 match_phrase,要求完全匹配用户搜索词,因为正文内容较多,且用户通过正文直接搜索的场景较少。
  • match_phrase_prefixwildcard
    • 代码块:使用 match_phrase_prefixwildcard,适用于用户通过方法名、API 接口路径等关键词搜索代码块。
  • 增强搜索
    • 针对非中文搜索,配置 wildcard 关键字,提升检索命中率。

DSL 配置示例

const DSL = {query: {bool: {filter: [{ term: { language } }],should: [...getTitleDSL(),     // 标题...getContentDSL(),   // 正文...getCodeDSL(),      // 代码块...enhanceApiSearchDSL(), // API 增强...enhanceNumberSearchDSL(), // 纯数字增强],},},highlight: getHighlightDSL(),from,size,_source: {exclude: ['h*.*'],},min_score: 1.0
};

配置策略

  • 标题
    • 使用 matchmatch_phrase_prefix
    • minimum_should_match: '80%':拆词后命中 80% 即可。
    • slop: 2:允许 2 个词的偏移。
  • 正文
    • 使用 match_phrase
    • 仅当用户完全匹配搜索词时,才算命中。
  • 代码块
    • 使用 match_phrase_prefixwildcard
    • 针对方法名、API 接口路径等关键词进行模糊匹配。
  • 增强搜索
    • 针对非中文搜索词,额外配置 wildcard 关键字,提升检索精度。

性能优化

  • 避免使用耗时的检索配置:
    • 例如,避免使用 wildcardfuzzy,减少搜索超时问题。
    • 根据业务需求合理配置 DSL,确保搜索效率。

9. 结果合并与排序策略

数据合并流程

  1. 确定数据比例
    • 根据场景决定 ES 和 Milvus 的数据占比。
    • 例如,正常情况下 ES 与 Milvus 的结果比例为 6:4。
    • 搜索词为变量名、纯数字等情况时,调整为 8:2。
  2. 评分归一化
    • 由于 Milvus 和 ES 的评分体系不同,需要进行归一化处理。
    • 每组数据的分数分别除以其最高分,统一评分标准。
  3. 精细化评分处理
    • ES 结果:乘以一个大于 1 的系数,确保 ES 的结果在合并后排名优先。
    • Milvus 结果:当 Milvus 搜索结果的分数(归一化前)超过 0.7 时,额外加分,提升其排名。
  4. 数据去重与合并
    • 合并 ES 和 Milvus 的搜索结果。
    • 去重处理,避免同一文档重复出现。
    • 根据最终评分排序,确保高相关性的结果排在前列。

示例代码

// Milvus 搜索调用示例
await app.milvus.search({collection_name: collection, // 集合名称partition_names,             // 分区名称vector: text_embs,           // 向量数据params: { nprobe: 16 },      // 搜索精度相关参数metric_type: searchConfig.metric_type, // 度量方式limit: limit ?? searchConfig.limit,    // 查询数量timeout: searchConfig.timeout,         // 超时时间offset: 0,                              // 从第0条开始查询filter: filter ?? null,                 // 过滤条件
});

配置参数说明

  • partition_names:根据文档的语言(中、英、日)选择相应的分区,提升搜索准确性。
  • nprobe:用于 IVF 检索类型,控制搜索的广度和精度。值越大,精度越高,但耗时增加。
  • metric_type:度量方式,如 IP(内积)或 L2(欧氏距离)。
  • limitoffset:一次性取多条数据,后端实现分页。
  • filter:如只搜索某个父类文档中的子文档,通过过滤条件缩小搜索范围。

分页处理

由于在文档存储阶段将长文档切割成多个片段并进行词嵌入,直接通过 Milvus 进行分页可能导致数据重复。因此,采用一次性取多条数据并在后端实现分页,确保用户体验和数据准确性。

性能优化

  • Milvus 检索速度:在当前数据量下,Milvus 的检索速度非常快,基本在几百毫秒内返回结果。
  • 资源配置:合理配置 nprobe 和搜索参数,平衡搜索精度和性能。

10. 总结与未来优化

关键要点总结

  1. ES 与 Milvus 的互补优势
    • ES:擅长关键词匹配,适用于基于关键词的全文搜索。
    • Milvus:擅长语义搜索,能够基于向量相似性找到语义相近的文档。
    • 结合使用:通过结合两者的优势,提升整体搜索效果和用户体验。
  2. 搜索架构设计
    • Milvus 辅助 ES:主要通过 Milvus 进行语义搜索,ES 进行关键词匹配,最终合并结果。
    • 评分策略:通过自定义评分调整,确保 Milvus 和 ES 的结果合理排序。
  3. 技术实现细节
    • 向量嵌入:使用词嵌入模型将搜索关键词转换为向量。
    • ES DSL 配置:根据文档类型(标题、正文、代码块)配置不同的搜索策略,提升搜索效率。
    • 结果合并与去重:通过归一化处理和去重,确保最终返回的搜索结果准确且不重复。
  4. Milvus Lite 的使用限制
    • 仅支持 FLAT 索引类型
    • 不支持分区及用户管理等高级功能。

未来优化建议

  1. 深入优化 ES 的 DSL 配置
    • 针对不同的搜索场景,进一步优化 ES 的 DSL 配置,提高搜索的精度和效率。
    • 避免使用耗时的搜索关键字,如 wildcardfuzzy,减少搜索超时问题。
  2. 模型优化与调优
    • 尝试不同的词嵌入模型,提升 Milvus 的语义搜索效果。
    • 根据业务需求,调整向量维度和搜索参数,优化搜索性能。
  3. 扩展 Milvus 的功能
    • 如果业务需要,考虑使用 Milvus 服务器部署,支持分区、索引类型扩展等高级功能。
    • 实现多语言支持,提升非中文场景下的搜索效果。
  4. 增强评分与排序策略
    • 根据用户反馈和数据分析,优化评分系数和排序策略,提升搜索结果的相关性。
    • 引入更多的评分维度,如文档的新旧程度、访问频率等,丰富评分体系。
  5. 用户体验提升
    • 实现关键词高亮显示,提升用户在搜索结果中的阅读体验。
    • 增加搜索结果的分类和过滤功能,帮助用户更快速地找到所需文档。
  6. 监控与维护
    • 实时监控 ES 和 Milvus 的运行状态,及时发现和解决性能瓶颈。
    • 定期备份 Milvus 数据,确保数据安全和可恢复性。

总结

通过结合 Elasticsearch 和 Milvus 的优势,本文展示了如何实现一个高效且准确的文档搜索系统。尽管目前的搜索点击率约为 65%,但相比单独使用 ES 或 Milvus,已经有了显著的提升。未来,通过持续优化搜索策略、模型和架构设计,预计搜索效果和用户体验将进一步提升。


参考资源

  • Milvus 官方文档:Milvus Docs
  • Milvus Migration 工具文档:Milvus Migration Tool
  • Milvus GitHub 仓库:Milvus GitHub
  • Elasticsearch 官方文档:Elasticsearch Docs
  • LangChain 与 Milvus 集成示例:LangChain Milvus Integration

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/61839.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flutter 设计模式全面解析:抽象工厂

设计模式作为软件开发中的经典解决方案,在 Flutter 的开发中也能为我们提供强大的架构支持。本文来介绍一下如何在 Flutter 中来实现抽象工厂设计模式,以及如何创建一系列相关或依赖对象并优雅地管理它们之间的复杂依赖关系。 日常开发中我们也能经常看…

AWS IAM 及其功能

IAM 代表身份和访问管理,可帮助控制谁可以进入云、访问 AWS 资源以及进入后可以做什么。 身份: IAM 帮助管理可以与 AWS 资源交互的身份(如用户名或服务帐户)。 访问:它决定每个身份可以在 AWS 服务上执行哪些操作&am…

SpringBoot集成Minio实现上传凭证、分片上传、秒传和断点续传

总体概述 Spring Boot整合Minio后,前端的文件上传有两种方式: 1.文件上传到后端,由后端保存到Minio 这种方式好处是完全由后端集中管理,可以很好的做到、身份验证、权限控制、文件与处理等,并且可以做一些额外的业务逻…

『 Linux 』网络层 - IP协议 (二)

文章目录 路由NAT技术分片与组装分片的组装IP协议分片的短板 路由 通常情况路由器具备了一个非常重要的功能,即构建子网; 同时路由器需要实现跨网络通信,说明路由器必须存在两个或以上的IP地址,通常在路由器中可以看到几个接口,分别是一个WAN口和几个LAN口; WAN口IP被称为公网I…

深度学习实战图像缺陷修复

这里写目录标题 概述1. 图像缺陷修复的研究背景2. 传统图像缺陷修复方法的局限性(1) 基于纹理合成的方法(2) 基于偏微分方程(PDE)的方法 3. 深度学习在图像缺陷修复中的兴起(1) 深度学习的基本思路(2) 深度学习方法的优势(3) 关键技术的引入 4. 深度学习…

vue从入门到精通(七):事件处理

1,事件的基本使用 1.使用v-on:xxx或 xxx 绑定事件,其中xxx是事件名2.事件的回调需要配置在methods对象中,最终会在vm上3.methods中配置的所数,不要用箭头函数!否则this就不是vm了4.methods中配置的函数,都是被Vue所管…

如何在 .gitignore 中仅保留特定文件:以忽略文件夹中的所有文件为例

在日常的开发工作中,使用 Git 来管理项目是不可或缺的一部分。项目中的某些文件夹可能包含大量的临时文件、生成文件或不需要版本控制的文件。在这种情况下,我们通常会使用 .gitignore 文件来忽略这些文件夹。然而,有时我们可能希望在忽略整个…

【SQL实验】索引操作(菜单操作和命令操作)

【代码是自己的解答,并非标准答案,也有可能写错,文中可能会有不准确或待完善之处,恳请各位读者不吝批评指正,共同促进学习交流】 文件”成绩管理”导入【具体操作前几篇文章详细展示过来,这里跳过。还是不太…

MVC 模型:架构与原理

MVC 模型:架构与原理 MVC(Model-View-Controller)模型是一种广泛应用于软件工程的架构模式,主要用于分离应用程序的逻辑层,以提高其可维护性和可扩展性。MVC模型将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。本文将深入探讨MVC模型的…

[pdf,epub]162页《分析模式》漫谈合集01-35提供下载

《分析模式》漫谈合集01-35的pdf、epub文件,已上传至本号的CSDN资源。 如果CSDN资源下载有问题,可到umlchina.com/url/ap.html。 已排版成适合手机阅读,pdf的排版更好一些。 ★UMLChina为什么叒要翻译《分析模式》? ★[缝合故事…

【Linux学习】【Ubuntu入门】1-7 ubuntu下磁盘管理

1.准备一个U盘或者SD卡(插上读卡器),将U盘插入主机电脑,右键点击属性,查看U盘的文件系统确保是FAT32格式 2.右键单击ubuntu右下角图标,将U盘与虚拟机连接 参考链接 3. Ubuntu磁盘文件:/dev/s…

Leetcode152. 乘积最大子数组(HOT100)

链接 代码&#xff1a; class Solution { public:int maxProduct(vector<int>& nums) {int f nums[0],g nums[0];int res nums[0];for(int i 1;i<nums.size();i){//int i 1 not int i 0 ,因为我们已经初始化好了首元素作为子数组的最大值和最小值int a n…

移远通信推出全新5G RedCap模组RG255AA系列,以更高性价比加速5G轻量化大规模商用

11月20&#xff0c;全球领先的物联网整体解决方案供应商移远通信宣布&#xff0c;正式推出其全新5G RedCap模组RG255AA系列。该系列模组支持5G NR独立组网&#xff08;SA&#xff09;和LTE Cat 4双模通信&#xff0c;具有高性能高集成度、低功耗、小尺寸、高性价比等优势&#…

【CVE-2024-9413】SCP-Firmware漏洞:安全通告

安全之安全(security)博客目录导读 目录 一、概述 二、修订历史 三、CVE根因分析 四、问题修复解决 一、概述 在SCP固件中发现了一个漏洞,如果利用该漏洞,可能会允许应用处理器(AP)在系统控制处理器(SCP)固件中导致缓冲区溢出。 CVE IDCVE-2024-9413受影响的产品SC…

数据集-目标检测系列- 花卉 玫瑰 检测数据集 rose >> DataBall

数据集-目标检测系列- 花卉 玫瑰 检测数据集 rose >> DataBall DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;持续增加中。 贵在坚持&#xff01; 数据样例项目地址&#xff1a; * 相关项目 1&#xff09;数据集可视化项…

详解Qt QTimeZone 时区类

文章目录 QTimeZone 详解前言什么是 QTimeZone&#xff1f;QTimeZone 的构造函数和常用成员函数构造函数1. 默认构造函数2. 指定时区 ID 构造函数3. 根据 UTC 偏移量构造 常用成员函数1. 获取时区 IDid 2. 检查时区是否有效isValid 3. 获取 UTC 偏移量offsetFromUtc 4. 检查是否…

Linux应用编程(C语言编译过程)

目录 1. 举例 2.预处理 2.1 预处理命令 2.2 .i文件内容解读 3.编译 4.汇编 5.链接 5.1 链接方式 5.1.1 静态链接 5.1.2 动态链接 5.1.3 混合链接 1. 举例 Linux的C语言开发&#xff0c;一般选择GCC工具链进行编译&#xff0c;通过下面的例子来演示GCC如何使用&#…

GitHub 开源项目 Puter :云端互联操作系统

每天面对着各种云盘和在线应用&#xff0c;我们常常会遇到这样的困扰。 文件分散在不同平台很难统一管理&#xff0c;付费订阅的软件越来越多&#xff0c;更不用说那些烦人的存储空间限制了。 最近在 GitHub 上发现的一个开源项目 Puter 彻底改变了我的在线办公方式。 让人惊…

Python 使用 OpenCV 将 MP4 转换为 GIF图

以下是使用 Python 和 OpenCV 将 MP4 转换为 GIF 的示例代码&#xff1a; python import cv2 import imageiodef mp4_to_gif(mp4_path, gif_path, fps10, start_timeNone, end_timeNone):"""将MP4视频转换为GIF动图。:param mp4_path: 输入MP4视频的路径。:pa…

el-table的树形结构后端返回的id没有唯一键怎么办

前端自己生成唯一键 首先尝试了表格的几个字段用-拼接成唯一键 但是仍报错 只好自己利用uuid库生成&#xff1b;