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

Milvus 核心设计(5)--- scalar indexwork mechanism

目录

背景

Scalar index 简介

属性过滤

扫描数据段

相似性搜索

返回结果

举例说明

1. 属性过滤

2. 扫描数据段

3. 相似性搜索

实际应用中的考虑

Scalar Index 方式

Auto indexing 

Inverted indexing


背景

继续Milvus的很细设计,前面主要阐述了Milvus 在 vector simalairity 上的处理策略及index 方式。今天主要讲下scalar index。应该说对于所有的 db 实现,scalar index 都是需要的,无论是否是 关系型数据库,还是是否采用 k-v 存储等模式,有的东西是触类旁通的。Milvus 在处理scalar index 时,并不是孤立处理,而是结合了 bitset 提前过滤 + vector similarity 共同应对user  query 提出的挑战。下面进入正题。

Scalar index 简介

向量相似性搜索过程中,Milvus 使用了属性过滤条件(expr)来扫描每个数据段(segment),并将过滤结果(bitset,一种位集合,用于高效表示哪些元素满足条件)与查询向量(data)一起应用于相似性搜索中。这种方式可以极大地提高搜索效率,因为它允许Milvus在执行耗时的相似性计算之前,先通过简单的属性过滤快速排除掉大量不满足条件的数据点。

具体来说,过程如下:

属性过滤

用户定义了一个或多个属性过滤条件(expr),这些条件用于筛选数据集中满足特定属性要求的向量。这些条件可以基于向量的元数据(如时间戳、地理位置、分类标签等)来定义。

扫描数据段

Milvus遍历或索引每个数据段,应用这些属性过滤条件。对于每个数据段,它会生成一个bitset,这个bitset中的每一位代表数据段中对应位置的向量是否满足过滤条件。

相似性搜索

在得到过滤后的bitset后,Milvus只针对那些标记为“满足条件”的向量进行相似性搜索。这意味着它不再需要计算所有向量的相似性,而只需计算那些经过初步筛选、更有可能与查询向量相似的向量的相似性。


返回结果

最后,Milvus根据相似性得分对满足条件的向量进行排序,并返回最相似的向量及其相关信息(如ID、相似度分数等)给用户。

这种结合属性过滤和相似性搜索的方法,使得Milvus在处理大规模向量数据集时,能够更加高效和准确地响应用户的查询需求。它特别适用于那些既需要基于内容的相似性搜索,又需要基于属性快速筛选的场景,如推荐系统、图像检索、文档聚类等领域。

这里有一点要说明,你使用milvus,基本决定了你的 collection 世界中,一定是 vector + scalar 共存的case,原因很简单,如果仅有scalar,我相信你使用 mysql,sqlserver,甚至oracle 足以,小的应用你甚至使用sqlite估计也行,因为你的 sql  query 足以胜任user 各种需求。你之所以选择向量数据库,肯定是要么有LLM的vector 需求,要么有pic,audio甚至video 的需求。还是那句话,使用场景决定了product 的选择。所以你的collection 多半可能是  一个+多个 vector embeddding + 多个 attibute 的vector 说明。

举例说明

假设我们有一个电商平台,该平台使用Milvus来存储商品的图像特征向量,并希望为用户提供基于图像相似性的商品推荐功能。同时,商品还具有一些属性信息,如价格、品牌、类别等。

1. 属性过滤

用户查询:用户希望找到一款与某张图片相似,但价格不超过5000元,且品牌为“Huawei”的商品。

属性过滤条件

  • 价格 <= 5000
  • 品牌 = "Huawei"

在Milvus中,这些属性信息会与图像特征向量一起存储,但它们是分开处理的。当用户发起查询时,Milvus首先会应用这些属性过滤条件来筛选出满足条件的商品。

2. 扫描数据段

数据段扫描

  • Milvus会将存储的商品数据分为多个数据段(segment),每个数据段包含一部分商品的特征向量和属性信息。
  • 当属性过滤条件被应用时,Milvus会遍历或索引这些数据段,检查每个商品是否满足过滤条件。
  • 对于满足条件的商品,Milvus会生成一个bitset,其中每个位对应一个商品,满足条件的商品对应的位被设置为1,不满足的则被设置为0。

3. 相似性搜索

相似性搜索

  • 在得到过滤后的bitset后,Milvus只针对那些标记为“满足条件”的商品特征向量进行相似性搜索。
  • 用户提供的查询图片首先被转换为特征向量。
  • Milvus使用适当的相似性度量(如余弦相似度)来计算查询向量与满足条件的商品特征向量之间的相似性。
  • 根据相似性得分,Milvus对商品进行排序,并返回最相似的几个商品给用户。

实际应用中的考虑

  • 性能优化:Milvus通过高效的索引结构和算法来加速数据段的扫描和相似性搜索过程,确保即使在处理大规模数据集时也能提供快速响应。
  • 多模态支持:Milvus不仅支持图像特征向量的存储和检索,还支持文本、音频等多种模态的数据,为跨模态检索提供了可能。
  • 可扩展性:Milvus支持分布式部署,可以随着数据量的增长而水平扩展,以满足更高并发和更大存储容量的需求。

Scalar Index 方式

Auto indexing 

你不用对你的scalar attribute 做任何辅助说明,Milvus 使用 auto indexing 的方式完成Scalar Indexing 的索引。

实际上你看了Milvus 的源码之后,你会发现,实际上 Auto indexing 就是 底层用的 inverted indexing。这里可能milvus 为了扩展,将inverted indexing 作为了 default 的 scalar indexing 来使用。

所以本质上来说要看下 Inverted indexing。

Inverted indexing

倒排索引,如果你曾经是比较资深的programmmer,你应该不会陌生。我那时候还没有ElasticSearch,用的是Lucene,后来有了ElasticSearch 和 Solr,但是万变不离其宗,其核心还是倒排索引。说直白点就是把一个句子拆分为词组的 tomkenizer 并 标识这些词在哪些句子中出现或是标识出现的概率。Milvus的 inverted indexing 出自一个开源库:Tantivy。应该说 Tantivy 的实现并不是ElasticSerach 或是 Solr,但是其思想有些类似,有兴趣的可以去看下源码。github 地址:

Tantivy Github 源码地址

再次说明了,成功是站在巨人的肩上,其实Milvus 用了不少其他中间件来保证自己的功能特性,前面介绍过的就有:etcd,mysql,rockMQ,pluster etc。现在又看到了 Tantivy。你可能会问为什么Milvus 不使用 ElasticSearch或Solr,那肯定是那啥License等问题,但从技术的角度来说,Tantivy也足够优秀。或许有一天 Tantivy 的知名度会超过 ElasticSearch 也不一定。

我们看个例子:

这就是倒排索引,只不过不同人,不同版本实现时,倒排信息的精度有差别,这里是focus 在句子层面。不过对于 Milvus的使用,足以。

在单个查询,比如上面的例子,品牌=’huawei‘,那根据倒排索引,直接锁定包含’huawei‘品牌attribute的 document 或 segment。

在区间查询,比如还是上面的例子,价格<5000, 那还是根据倒排索引,直接锁定 价格 attribute的document 或segment。

或许区间的例子还不够透彻,因为range 的是数据。你查找的品牌获取不止一种,如果 brand in ['huawei', 'apple'] 首先会经过类似alpha的字母排序,之后通过倒排索引查询,会比暴力查询效率高很多。

相关文章:

  • 华为HCIP Datacom H12-821 卷40
  • FPGA上板项目(二)——PLL测试
  • c++单例模式
  • 「Conda」在Linux系统中安装Conda环境管理器
  • python安全脚本开发简单思路
  • SpringBoot+Vue实现简单的文件上传(txt篇)
  • 华为USG6000V防火墙v1
  • 【区块链 + 智慧政务】城市公积金中心区块链基础服务平台 | FISCO BCOS应用案例
  • 网络安全工作者如何解决网络拥堵
  • Centos---命令详解 vi 系统服务 网络
  • 【C语言】深入解析选择排序
  • 音视频入门基础:H.264专题(13)——FFmpeg源码中通过SPS属性获取视频色彩格式的实现
  • PyTorch张量创建和随机数生成器算法
  • 【区块链 + 智慧政务】区块链 +ETC 下一代公路联网收费关键技术优化项目 | FISCO BCOS应用案例
  • 去除重复数字
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • JAVA并发编程--1.基础概念
  • JWT究竟是什么呢?
  • mongo索引构建
  • nodejs:开发并发布一个nodejs包
  • Service Worker
  • vue--为什么data属性必须是一个函数
  • 通信类
  • 消息队列系列二(IOT中消息队列的应用)
  • 一文看透浏览器架构
  • 正则表达式
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • ​如何防止网络攻击?
  • ###项目技术发展史
  • #if 1...#endif
  • #Linux(Source Insight安装及工程建立)
  • #mysql 8.0 踩坑日记
  • #vue3 实现前端下载excel文件模板功能
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (搬运以学习)flask 上下文的实现
  • (层次遍历)104. 二叉树的最大深度
  • (动态规划)5. 最长回文子串 java解决
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (黑马C++)L06 重载与继承
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (南京观海微电子)——I3C协议介绍
  • (转)winform之ListView
  • (转)程序员技术练级攻略
  • .gitignore文件忽略的内容不生效问题解决
  • .NET6 开发一个检查某些状态持续多长时间的类
  • .NET和.COM和.CN域名区别
  • .net中应用SQL缓存(实例使用)
  • @Async 异步注解使用
  • [ACM独立出版] 2024年虚拟现实、图像和信号处理国际学术会议(VRISP 2024,8月2日-4)
  • [C++] 从零实现一个ping服务
  • [C语言]——分支和循环(4)
  • [Hello-algo] 复杂度分析
  • [iOS]-NSTimer与循环引用的理解