当前位置: 首页 > news >正文

Elasticsearch vs 向量数据库:寻找最佳混合检索方案

5010ec6e3c4867144ff20c114c4ea384.png

e88aba3f86d5bf29c9831eb00a7827f7.png

图片来自Shutterstock上的Bakhtiar Zein

多年来,以Elasticsearch为代表的基于全文检索的搜索方案,一直是搜索和推荐引擎等信息检索系统的默认选择。但传统的全文搜索只能提供基于关键字匹配的精确结果,例如找到包含特殊名词“Python3.9”的文档,或是找到带“花”字,“雨”字,“雪”字的古诗词。

但在实际需求中,我们有时候需要的,不只是古诗词中带“雪”字,还要找到表示雪很大这样意向的古诗词。比如,初高中语文课里学到的“忽如一夜春风来,千树万树梨花开”这句诗,虽然没有雪字,却精准表达了雪很大这样的意向。

再以照片检索为例,我们不仅需要1:1精准搜索出图像对应的原图,往往也需要对图像的特征、关键信息提取后,去检索具备类似特征的图像,完成以图搜图或者内容推荐等任务。

如何通过检索得到以上结果?

基于稠密向量打造的语义搜索就发挥了作用。通常来说,语义检索,通过将我们输入的词汇、图片、语音等原始数据转化为向量,进而捕捉不同数据之间的语义关系(例如知道“老师”和“教师”其实是一个意思),可以更精准的理解用户的搜索意图,从而提供更准确、更相关的搜索结果。

但如何实现语义检索?Embedding模型和向量数据库在其中的作用至关重要。前者主要完成原始信息的向量化,后者则提供对向量化信息的存储、检索等服务。目前,检索增强生成(RAG)与多模态搜索,是语义检索的核心应用场景之一。

但通常来说,在实践中,全文检索与语义检索不是非此即彼的关系。我们需要同时兼顾语义理解和精确的关键字匹配。比如学术论文的写作中,用户不仅希望在搜索结果看到与搜索查询相关的概念,同时也希望保留查询中使用的原始信息返回搜索结果,比如基于一些特殊术语和名称。

因此,许多搜索应用正在采用混合搜索方法,结合两种方法的优势,以平衡灵活的语义相关性和可预测的精确关键字匹配。

01.

混合搜索挑战

实现混合搜索的常见方法如下:

先使用像开源Milvus这样的专用向量数据库,进行高效和可扩展的语义搜索;

然后使用像Elasticsearch或OpenSearch这样的传统搜索引擎进行全文搜索。

两两搭配虽然效果不错,但也引入了新的复杂性:首先,搭配两套不同的搜索系统,也就意味着我们要同时管理不同的基础设施、配置和维护任务。这会造成更重的运营负担并增加潜在的集成问题。

305db12d460d7eb43f892c04d72991ae.png

在此基础上,混合检索统一解决方案横空出世。

混合搜索的统一解决方案将提供许多好处:

  • 减少基础设施维护:管理一个系统而不是两个系统大大降低了操作复杂性,节省了时间和资源。这也意味着更少的上下文切换和掌握两组不同API的算力开销。

  • 合并数据管理:统一的表结构允许用户将密集(基于向量)和稀疏(基于关键字)数据与共享元数据标签一起存储。使用两个单独的系统,则需要将元数据标签存储两次,以便双方能够进行元数据过滤。

  • 简化查询:单个请求可以执行语义和全文搜索任务,无需对单独的系统进行两次API调用。

  • 增强的安全性和权限改造:统一的方法可以实现更直接和更强大的安全管理,因为所有访问控制都可以在向量数据库中集中管理,从而提高安全性合规性和一致性。

02.

如何使用统一的向量方法简化混合搜索

在语义搜索中,机器学习模型会根据文本的含义将文本“嵌入”为高维空间中的点(称为密集向量) 。具有相似语义的文本在此空间中,彼此的距离会更接近。例如,“苹果”和“水果”就比“苹果”和“汽车”更接近。这使得我们能够通过使用近似最近邻 (ANN)算法计算每个点之间的距离来快速找到语义相关的文本。

这种方法也可以通过将文档和查询编码为稀疏向量,进而应用于全文搜索。

在稀疏向量中,每个维度代表一个术语,值表示每个术语在文档中的重要性。

文档中不存在的术语的值为零。由于任何给定的文档通常只使用词汇表中所有可能术语的一小部分,因此,大多数术语不会出现在文档中。这也就意味着生成的向量是稀疏的——因为它们的大多数值为零。例如,在通常用于评估信息检索任务的MS-MARCO数据集中,虽然大约有 900 万个文档,100 万个词,但大多数文档只覆盖不足几百个词,生成的向量中绝大多数维度值为零。

这种极端稀疏性对于我们高效存储和处理这些向量具有重要意义。比如,我们可以将其用于优化搜索性能,同时保持准确性

最初为密集向量设计的向量数据库,其实也可以高效处理这些稀疏向量。例如,开源向量数据库Milvus刚刚发布了使用Sparse-BM25的原生全文搜索功能。

Sparse-BM25 由 Milvus提出,其原理类似 Elasticsearch 和其他全文搜索系统中常用的BM25算法,但针对稀疏向量设计,可以实现相同效果的全文搜索功能:

  • 具有数据剪枝功能的高效检索算法:通过剪枝来丢弃搜索查询中的低值稀疏向量,向量数据库可以显著减小索引大小并以最小的质量损失达成最优的性能。

  • 带来进一步的性能优化:将词频表示为稀疏向量而不是倒排索引,可以实现其他基于向量的优化。比如:用图索引替代暴力扫描,实现更有效的搜索;乘积量化(PQ)/标量量化(SQ),进一步减少内存占用。

除了这些优化之外,Sparse-BM25还继承了高性能向量数据库Milvus的几个系统级优势:

  • 高效的底层实现和内存管理:Milvus 的核心向量索引引擎采用 C++ 实现,可以提供比基于Java的系统(如Elasticsearch)更高效的内存管理。与基于JVM的方法相比,仅此一项就节省了数 GB 的内存占用。

  • 对MMap的支持:与Elasticsearch在内存和磁盘中使用page-cache进行索引存储类似,Milvus支持内存映射(MMap)以在索引超过可用内存时扩展内存容量。

03.

为什么传统搜索引擎在向量搜索方面有先天不足

Elasticsearch是为传统的倒排索引构建的,在不根本改变架构的情况下,支持向量索引具有非常大的挑战。这导致其相比于专用向量数据库有非常大的性能差异:即使只有100万个向量,Elasticsearch也需要200毫秒(在全托管的 Elastic Cloud 上测试)才能返回搜索结果,而在Milvus上(在全托管的Zilliz Cloud上测试)需要6毫秒——性能差异超过30倍。

每秒查询率(QPS)测量的吞吐量也有3倍的差异,Zilliz Cloud上性能最高的实例运行在6,000QPS,而Elastic Cloud最多为1,900QPS。此外,Zilliz Cloud在加载向量数据和构建索引方面比Elastic Cloud快15倍。

此外,Elasticsearch的Java/JVM实现导致其性能的可扩展性也弱于基于 C++/Go 实现的向量数据库。而且,Elasticsearch缺乏高级的向量搜索功能,如基于磁盘的索引(DiskANN、MMap)、优化的元数据过滤和range search。

dc23e39ee16180fab3f1e3cebffba037.png

04.

结论

Milvus 作为性能领先的向量数据库,通过无缝结合语义搜索和全文搜索,将稠密向量搜索与优化的稀疏向量技术相结合,提供了卓越的性能、可扩展性和效率,并简化了基础设施的部署难度,降低成本的同时还增强了搜索能力。

展望未来,我们相信基于向量数据库的新型基础设施,将有望超越Elasticsearch成为混合搜索的标准解决方案。

作者介绍

20bebd16340baeb53ed3860f994aaa12.jpeg

陈将

Zilliz 生态和 AI 平台负责人

推荐阅读

273cffe03551c82b5ac14b111ff8ea11.png

262e47c1f22d5891d238bc91c145df2f.png

70ec2eb41c6fe3f867ee9510c654520e.png

096d76e59609d55aea6bb6083acd6552.png

相关文章:

Elasticsearch vs 向量数据库:寻找最佳混合检索方案

图片来自Shutterstock上的Bakhtiar Zein 多年来,以Elasticsearch为代表的基于全文检索的搜索方案,一直是搜索和推荐引擎等信息检索系统的默认选择。但传统的全文搜索只能提供基于关键字匹配的精确结果,例如找到包含特殊名词“Python3.9”的文…...

【Flink-scala】DataStream编程模型之水位线

DataStream API编程模型 1.【Flink-Scala】DataStream编程模型之 数据源、数据转换、数据输出 2.【Flink-scala】DataStream编程模型之 窗口的划分-时间概念-窗口计算程序 3.【Flink-scala】DataStream编程模型之 窗口计算-触发器-驱逐器 文章目录 DataStream API编程模型前言…...

Python导入moviepy找不到editor 视频没有声音设置audio_codec参数

moviepy合成视频出错: 问题一:导入moviepy.editor找不到editor,No module named moviepy.editor问题二:合成的视频没有声音 问题一:导入moviepy.editor找不到editor,No module named moviepy.editor from …...

rsync 是一个非常强大的 Linux 工具,常用于文件和目录的同步、备份和传输。

rsync 是一个非常强大的 Linux 工具,常用于文件和目录的同步、备份和传输。它可以高效地同步本地和远程系统上的文件和目录,并且支持增量传输,仅同步发生变化的部分。rsync 支持压缩传输、删除多余文件、排除特定文件等多种功能,是日常运维、备份和迁移数据的重要工具。 一…...

触发器案例详解

目录 一、定义二、类型三、功能与用途四、创建与调用DML触发器格式示例DDL触发器格式示例登录触发器格式示例五、案例案例一:DML触发器 - 记录更新操作的触发器案例二:DML触发器 - 防止非法工资更新的触发器案例三:DDL触发器 - 记录表结构更改的触发器案例四:DDL触发器 - 防…...

jwt 与 sessionid 的区别及应用场景

在现代 Web 应用中,JWT(JSON Web Token)和SessionID是两种常用的用户认证和状态管理机制。本文从两者的原理、区别、优缺点以及适用场景展开分析,结合常见问题提出了最佳实践建议,帮助开发者更好地选择和使用。 JWT与S…...

tomcat和nginx

Tomcat 和 Nginx 都可以部署 Web 应用,但它们的核心功能和适用场景不同,因此在 2024 年生产环境及未来,是否使用 Tomcat 取决于需求和技术架构的特点。 1. Tomcat 的特点与适用场景 Tomcat 是 Java Servlet 容器,主要用来运行基于…...

服务器带宽与数据安全的重要性与作用

服务器带宽指的是服务器与外部网络通信的能力,即服务器发送和接收数据的速率。带宽越大,服务器在同一时间内能够处理的数据量就越多,数据传输的速度和稳定性也就越高。在数字化时代,企业对于数据的依赖程度日益加深,无…...

JSON数据处理

1. JSON注解 Data NoArgsConstructor AllArgsConstructor JsonIgnoreProperties(ignoreUnknowntrue) JSON注解: JsonIgnoreProperties(ignoreUnknowntrue) Hutool 日期格式化: DatePattern DateTimeFormat(pattern "yyyy-MM-dd HH:mm:ss")…...

FSWIND脉动风-风载时程生成器软件原理

大量风的实测资料表明,在风的时程曲线中,瞬时风速包含两个部分:一部分是自振周期一般在 10 分钟以上的平均风,另一部分是周期一般只有几秒左右的脉动风。平均风由于其周期一般比结构的自振周期大,因而考虑其作用性质相…...

搭建高可用负载均衡系统:Nginx 与云服务的最佳实践

搭建高可用负载均衡系统:Nginx 与云服务的最佳实践 引言 在项目开发过程中,我们通常在开发和测试阶段采用单机架构进行开发和测试。这是因为在这个阶段,系统的主要目的是功能实现和验证,单机架构足以满足开发人员的日常需求&…...

对比git命令与TortoiseGit工具,理解git解决冲突的过程

1 引言 此前用TortoiseSvn习惯了,所以,转到git时也同时选择了TortoiseGit工具。 同时,对比了可视化工具和git命令的操作,来深入理解git解决冲突的方式。 2 使用远程仓库替代本地仓库的内容 2.1 TortoiseGit做法 using “MERGE_…...

guava缓存的get方法的回调函数讲解一下

CacheBuilder.newBuilder()//设置缓存初始大小,应该合理设置,后续会扩容.initialCapacity(10)//最大值.maximumSize(100)//并发数设置.concurrencyLevel(5)//缓存过期时间,写入后10分钟过期.expireAfterWrite(600,TimeUnit.SECONDS)//统计缓存…...

React基础知识四 Hooks

什么是hooks? (coderwhy) hooks是react 16.8(2019年)出的新特性。 react有两种形式来创建组件——类式和函数式。在hooks之前类式组件就是react最主流的编程方式。 这个时候,函数式组件是非常鸡肋的,几乎没什么用。因…...

线性代数中的谱分解

一、谱分解的基本原理 谱分解(Spectral Decomposition)是线性代数中的一个重要概念,特别是在研究矩阵的特征值和特征向量时。它指的是将一个矩阵分解为其特征值和特征向量的组合,从而简化矩阵的运算和分析。谱分解通常适用于对称…...

Redis 数据结结构(一)—字符串、哈希表、列表

Redis(版本7.0)的数据结构主要包括字符串(String)、哈希表(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)、超日志&#xff08…...

【Python】用Python和Paramiko实现远程服务器自动化管理

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在现代IT环境中,远程服务器管理已成为运维工作的常态。随着自动化运维的需求不断增加,如何高效地管理远程服务器,提升操作的灵活性和效率…...

PDF处理的创新工具:福昕低代码平台尝鲜

在当今数字化时代,PDF文件的处理和管理变得越来越重要。福昕低代码平台是新发布的一款创新的工具,旨在简化PDF处理和管理的流程。通过这个平台,用户可以通过简单的拖拽界面上的按钮,轻松完成对Cloud API的调用工作流,而…...

openstack创建浮动IP全过程

1、创建外部网络,即是provider网络,有关provider网络的详细解释请参见我之前的文章openstack中的self-service和provider网络_openstack provider网络不能创建vlan吗-CSDN博客 network create --share --external --provider-physical-network physnet1…...

nginx漏洞修复

漏洞名称:web服务器http信息头公开 解决,在以下各个监听端口加上一行,然后重启****nginx server_tokens off; 漏洞名称:默认的nginx http服务器设置 解决:请求头加上以下参数 add_header Content-Security-Policy “…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 ​…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景

Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...

数据库正常,但后端收不到数据原因及解决

从代码和日志来看,后端SQL查询确实返回了数据,但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离,并且ai辅助开发的时候,很容易出现前后端变量名不一致情况,还不报错,只是单…...

渗透实战PortSwigger Labs指南:自定义标签XSS和SVG XSS利用

阻止除自定义标签之外的所有标签 先输入一些标签测试&#xff0c;说是全部标签都被禁了 除了自定义的 自定义<my-tag onmouseoveralert(xss)> <my-tag idx onfocusalert(document.cookie) tabindex1> onfocus 当元素获得焦点时&#xff08;如通过点击或键盘导航&…...

第21节 Node.js 多进程

Node.js本身是以单线程的模式运行的&#xff0c;但它使用的是事件驱动来处理并发&#xff0c;这样有助于我们在多核 cpu 的系统上创建多个子进程&#xff0c;从而提高性能。 每个子进程总是带有三个流对象&#xff1a;child.stdin, child.stdout和child.stderr。他们可能会共享…...

Java毕业设计:办公自动化系统的设计与实现

JAVA办公自动化系统 一、系统概述 本办公自动化系统基于Java EE平台开发&#xff0c;实现了企业日常办公的数字化管理。系统包含文档管理、流程审批、会议管理、日程安排、通讯录等核心功能模块&#xff0c;采用B/S架构设计&#xff0c;支持多用户协同工作。系统使用Spring B…...

Linux 进程管理学习指南:架构、计划与关键问题全解

Linux 进程管理学习指南&#xff1a;架构、计划与关键问题全解 本文面向初学者&#xff0c;旨在帮助你从架构视角理解 Linux 进程管理子系统&#xff0c;构建系统化学习路径&#xff0c;并通过结构化笔记方法与典型问题总结&#xff0c;夯实基础、明确方向&#xff0c;逐步掌握…...