Milvus(24):全文搜索、文本匹配

1 全文搜索

        全文搜索是一种在文本数据集中检索包含特定术语或短语的文档,然后根据相关性对结果进行排序的功能。该功能克服了语义搜索的局限性(语义搜索可能会忽略精确的术语),确保您获得最准确且与上下文最相关的结果。此外,它还通过接受原始文本输入来简化向量搜索,自动将您的文本数据转换为稀疏嵌入,而无需手动生成向量嵌入。

        该功能使用 BM25 算法进行相关性评分,在检索增强生成 (RAG) 场景中尤为重要,它能优先处理与特定搜索词密切匹配的文档。

1.1 概述

        全文搜索无需手动嵌入,从而简化了基于文本的搜索过程。该功能通过以下工作流程进行操作符:

  1. 文本输入:插入原始文本文档或提供查询文本,无需手动嵌入。
  2. 文本分析:Milvus 使用分析器将输入文本标记为可搜索的单个术语。
  3. 函数处理:内置函数接收标记化术语,并将其转换为稀疏向量表示。
  4. Collections 存储:Milvus 将这些稀疏嵌入存储在 Collections 中,以便高效检索。
  5. BM25 评分:在搜索过程中,Milvus 应用 BM25 算法为存储的文档计算分数,并根据与查询文本的相关性对匹配结果进行排序。

1.2 创建用于全文搜索的 Collections

        要启用全文搜索,请创建一个具有特定 Schema 的 Collections。此 Schema 必须包括三个必要字段:

  • 唯一标识 Collections 中每个实体的主字段。
  • 一个VARCHAR 字段,用于存储原始文本文档,其enable_analyzer 属性设置为True 。这允许 Milvus 将文本标记为特定术语,以便进行函数处理。
  • 一个SPARSE_FLOAT_VECTOR 字段,预留用于存储稀疏嵌入,Milvus 将为VARCHAR 字段自动生成稀疏嵌入。

1.2.1 定义 Collections 模式

        首先,创建 Schema 并添加必要的字段:

from pymilvus import MilvusClient, DataType, Function, FunctionTypeclient = MilvusClient(uri="http://localhost:19530",token="root:Milvus"
)schema = MilvusClient.create_schema()schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True, auto_id=True)
schema.add_field(field_name="text", datatype=DataType.VARCHAR, max_length=1000, enable_analyzer=True)
schema.add_field(field_name="sparse", datatype=DataType.SPARSE_FLOAT_VECTOR)

        在此配置中

  • id: 作为主键,并通过auto_id=True 自动生成。
  • text:存储原始文本数据,用于全文搜索操作。数据类型必须是VARCHAR ,因为VARCHAR 是 Milvus 用于文本存储的字符串数据类型。设置enable_analyzer=True 以允许 Milvus 对文本进行标记化。默认情况下,Milvus 使用standard分析器进行文本分析。
  • sparse矢量字段:用于存储内部生成的稀疏嵌入的矢量字段,以进行全文搜索操作。数据类型必须是SPARSE_FLOAT_VECTOR 。

        现在,定义一个将文本转换为稀疏向量表示的函数,然后将其添加到 Schema 中:

bm25_function = Function(name="text_bm25_emb", # 函数名input_field_names=["text"], # 包含原始文本数据的VARCHAR字段的名称output_field_names=["sparse"], # SPARSE_FLOAT_VECTOR字段的名称,用于存储生成的嵌入function_type=FunctionType.BM25, # 设置为“BM25”
)schema.add_function(bm25_function)

参数

说明

name

函数名称。该函数将text 字段中的原始文本转换为可搜索向量,这些向量将存储在sparse 字段中。

input_field_names

需要将文本转换为稀疏向量的VARCHAR 字段的名称。对于FunctionType.BM25 ,该参数只接受一个字段名称。

output_field_names

存储内部生成的稀疏向量的字段名称。对于FunctionType.BM25 ,该参数只接受一个字段名称。

function_type

要使用的函数类型。将值设为FunctionType.BM25 。

        对于有多个VARCHAR 字段需要进行文本到稀疏向量转换的 Collections,请在 Collections Schema 中添加单独的函数,确保每个函数都有唯一的名称和output_field_names 值。

1.2.2 配置索引

        在定义了包含必要字段和内置函数的 Schema 后,请为 Collections 设置索引。为简化这一过程,请使用AUTOINDEX 作为index_type ,该选项允许 Milvus 根据数据结构选择和配置最合适的索引类型。

index_params = MilvusClient.prepare_index_params()index_params.add_index(field_name="sparse",index_type="SPARSE_INVERTED_INDEX",metric_type="BM25",params={"inverted_index_algo": "DAAT_MAXSCORE","bm25_k1": 1.2,"bm25_b": 0.75}
)

参数

参数

field_name

要索引的向量字段的名称。对于全文搜索,这应该是存储生成的稀疏向量的字段。在本示例中,将值设为sparse 。

index_type

要创建的索引类型。AUTOINDEX 允许 Milvus 自动优化索引设置。如果需要对索引设置进行更多控制,可以从 Milvus 中稀疏向量可用的各种索引类型中进行选择。

metric_type

该参数的值必须设置为BM25 ,专门用于全文搜索功能。

params

特定于索引的附加参数字典。

params.inverted_index_algo

用于构建和查询索引的算法。有效值:

  • "DAAT_MAXSCORE" (默认):使用 MaxScore 算法优化的一次文档 (DAAT) 查询处理。MaxScore 通过跳过可能影响最小的术语和文档,为高k值或包含大量术语的查询提供更好的性能。为此,它根据最大影响分值将术语划分为基本组和非基本组,并将重点放在对前 k 结果有贡献的术语上。

  • "DAAT_WAND":使用 WAND 算法优化 DAAT 查询处理。WAND 算法利用最大影响分数跳过非竞争性文档,从而评估较少的命中文档,但每次命中的开销较高。这使得 WAND 对于k值较小的查询或较短的查询更有效,因为在这些情况下跳过更可行。

  • "TAAT_NAIVE":基本术语一次查询处理(TAAT)。虽然与DAAT_MAXSCORE 和DAAT_WAND 相比速度较慢,但TAAT_NAIVE 具有独特的优势。DAAT 算法使用的是缓存的最大影响分数,无论全局 Collections 参数(avgdl)如何变化,这些分数都是静态的,而TAAT_NAIVE 不同,它能动态地适应这种变化。

params.bm25_k1

控制词频饱和度。数值越高,术语频率在文档排名中的重要性就越大。取值范围[1.2, 2.0].

params.bm25_b

控制文档长度的标准化程度。通常使用 0 到 1 之间的值,默认值为 0.75 左右。值为 1 表示不进行长度归一化,值为 0 表示完全归一化。

1.2.3 创建 Collections

        现在使用定义的 Schema 和索引参数创建 Collections。

client.create_collection(collection_name='my_collection', schema=schema, index_params=index_params
)

1.3 插入文本数据

        设置好集合和索引后,就可以插入文本数据了。在此过程中,您只需提供原始文本。我们之前定义的内置函数会为每个文本条目自动生成相应的稀疏向量。

client.insert('my_collection', [{'text': 'information retrieval is a field of study.'},{'text': 'information retrieval focuses on finding relevant information in large datasets.'},{'text': 'data mining and information retrieval overlap in research.'},
])

1.4 执行全文搜索

        将数据插入 Collections 后,就可以使用原始文本查询执行全文检索了。Milvus 会自动将您的查询转换成稀疏向量,并使用 BM25 算法对匹配的搜索结果进行排序,然后返回 topK (limit) 结果。

search_params = {'params': {'drop_ratio_search': 0.2},
}client.search(collection_name='my_collection', data=['whats the focus of information retrieval?'],anns_field='sparse',limit=3,search_params=search_params
)

参数

说明

search_params

包含搜索参数的字典。

params.drop_ratio_search

搜索过程中要忽略的低重要性词的比例。

data

原始查询文本。

anns_field

包含内部生成的稀疏向量的字段名称。

limit

要返回的最大匹配次数。

2 文本匹配

        Milvus 的文本匹配功能可根据特定术语精确检索文档。该功能主要用于满足特定条件的过滤搜索,并可结合标量过滤功能来细化查询结果,允许在符合标量标准的向量内进行相似性搜索。

2.1 概述

        Milvus 整合了Tantivy来支持其底层的倒排索引和基于术语的文本搜索。对于每个文本条目,Milvus 都会按照以下程序建立索引:

  1. 分析器:分析器将输入文本标记化为单个词或标记,然后根据需要应用过滤器。这样,Milvus 就能根据这些标记建立索引。
  2. 编制索引:文本分析完成后,Milvus 会创建一个倒排索引,将每个独特的标记映射到包含该标记的文档。

        当用户进行文本匹配时,倒排索引可用于快速检索包含该术语的所有文档。这比逐个扫描每个文档要快得多。

2.2 启用文本匹配

        文本匹配适用于VARCHAR 字段类型,它本质上是 Milvus 中的字符串数据类型。要启用文本匹配,请将enable_analyzer 和enable_match 都设置为True ,然后在定义 Collections Schema 时选择性地配置分析器进行文本分析。

2.2.1 将enable_analyzer 和enable_match

        要启用特定VARCHAR 字段的文本匹配,请在定义字段 Schema 时将enable_analyzer 和enable_match 参数设置为True 。这将指示 Milvus 对文本进行标记化处理,并为指定字段创建反向索引,从而实现快速高效的文本匹配。

from pymilvus import MilvusClient, DataTypeschema = MilvusClient.create_schema(enable_dynamic_field=False)
schema.add_field(field_name="id",datatype=DataType.INT64,is_primary=True,auto_id=True
)
schema.add_field(field_name='text', datatype=DataType.VARCHAR, max_length=1000, enable_analyzer=True, # 是否为此字段启用文本分析enable_match=True # 是否启用文本匹配
)
schema.add_field(field_name="embeddings",datatype=DataType.FLOAT_VECTOR,dim=5
)

2.2.2 可选:配置分析器

        关键词匹配的性能和准确性取决于所选的分析器。不同的分析器适用于不同的语言和文本结构,因此选择正确的分析器会极大地影响特定用例的搜索结果。默认情况下,Milvus 使用standard 分析器,该分析器根据空白和标点符号对文本进行标记,删除长度超过 40 个字符的标记,并将文本转换为小写。应用此默认设置无需额外参数。

        如果需要不同的分析器,可以使用analyzer_params 参数进行配置。例如,应用english 分析器处理英文文本:

analyzer_params = {"type": "english"
}
schema.add_field(field_name='text',datatype=DataType.VARCHAR,max_length=200,enable_analyzer=True,analyzer_params = analyzer_params,enable_match = True,
)

2.3 使用文本匹配

        为 Collections Schema 中的 VARCHAR 字段启用文本匹配后,就可以使用TEXT_MATCH 表达式执行文本匹配。

2.3.1 文本匹配表达式语法

   TEXT_MATCH 表达式用于指定要搜索的字段和术语。其语法如下:

TEXT_MATCH(field_name, text)
  • field_name:要搜索的 VARCHAR 字段的名称。
  • text:要搜索的术语。根据语言和配置的分析器,多个术语可以用空格或其他适当的分隔符分隔。

        默认情况下,TEXT_MATCH 使用OR匹配逻辑,即返回包含任何指定术语的文档。例如,要搜索text 字段中包含machine 或deep 的文档,请使用以下表达式:

filter = "TEXT_MATCH(text, 'machine deep')"

        还可以使用逻辑操作符组合多个TEXT_MATCH 表达式来执行AND匹配。要搜索text 字段中同时包含machine 和deep 的文档,请使用以下表达式:

filter = "TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'deep')"

        要搜索text 字段中同时包含machine 和learning 但不包含deep 的文档,请使用以下表达式:

filter = "not TEXT_MATCH(text, 'deep') and TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'learning')"

2.3.2 使用文本匹配搜索

        文本匹配可与向量相似性搜索结合使用,以缩小搜索范围并提高搜索性能。通过在向量相似性搜索前使用文本匹配过滤 Collections,可以减少需要搜索的文档数量,从而加快查询速度。

        在这个示例中,filter 表达式过滤了搜索结果,使其只包含与指定术语keyword1 或keyword2 匹配的文档。然后在这个过滤后的文档子集中执行向量相似性搜索。

# 匹配带有‘ keyword1 ’或‘ keyword2 ’的实体
filter = "TEXT_MATCH(text, 'keyword1 keyword2')"# 假设‘embeddings’是向量字段,‘text’是VARCHAR字段
result = client.search(collection_name="my_collection", # 集合名称anns_field="embeddings", # 向量字段名data=[query_vector], # 查询向量filter=filter,search_params={"params": {"nprobe": 10}},limit=10, # Max。要返回的结果数output_fields=["id", "text"] 
)

2.3.3 文本匹配查询

        文本匹配也可用于查询操作中的标量过滤。通过在query() 方法的expr 参数中指定TEXT_MATCH 表达式,可以检索与给定术语匹配的文档。下面的示例检索了text 字段包含keyword1 和keyword2 这两个术语的文档。

# 匹配包含‘ keyword1 ’和‘ keyword2 ’的实体
filter = "TEXT_MATCH(text, 'keyword1') and TEXT_MATCH(text, 'keyword2')"result = client.query(collection_name="my_collection",filter=filter, output_fields=["id", "text"]
)

2.4 注意事项

        为字段启用术语匹配会触发反向索引的创建,从而消耗存储资源。在决定是否启用此功能时,请考虑对存储的影响,因为它根据文本大小、唯一标记和所使用的分析器而有所不同。

        在 Schema 中定义分析器后,其设置将永久适用于该 Collections。如果您认为不同的分析器更适合您的需要,您可以考虑删除现有的 Collections,然后使用所需的分析器配置创建一个新的 Collections。

   filter 表达式中的转义规则:

  • 表达式中用双引号或单引号括起来的字符被解释为字符串常量。如果字符串常量包含转义字符,则必须使用转义序列来表示转义字符。例如,用\\ 表示\ ,用\\t 表示制表符\t ,用\\n 表示换行符。

  • 如果字符串常量由单引号括起来,常量内的单引号应表示为\\' ,而双引号可表示为" 或\\" 。 示例:'It\\'s milvus' 。

  • 如果字符串常量由双引号括起来,常量中的双引号应表示为\\" ,而单引号可表示为' 或\\' 。 示例:"He said \\"Hi\\"" 

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

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

相关文章

2000 元以下罕见的真三色光源投影仪:雷克赛恩Cyber Pro1重新定义入门级投影体验

当性价比遇上技术瓶颈 在 2000元以下的1080P投影仪,单LCD 技术长期主导。而三色光源的DLP和3LCD真1080P都在4000元以上。 单LCD投影为纯白光光源,依赖CF滤光膜导致光效低下,普遍存在" 色彩失真 " 等问题。数据显示,该价…

Maven 下载安装与配置教程

## 1. Maven 简介 Maven 是一个项目管理和构建自动化工具,主要用于 Java 项目。Maven 可以帮助开发者管理项目的构建、报告和文档,简化项目依赖管理。 ## 2. 下载 Maven 1. 访问 Maven 官方网站 [https://maven.apache.org/download.cgi](https://maven.…

C# 深入理解类(从类的外部访问静态成员)

从类的外部访问静态成员 在前一章中,我们看到使用点运算符可以从类的外部访问public实例成员。点运算符由实 例名、点和成员名组成。 就像实例成员,静态成员也可以使用点运算符从类的外部访问。但因为没有实例,所以最常 用的访问静态成员的方…

Java在微服务架构中的最佳实践:从设计到部署

在2025年的云计算和分布式系统时代,微服务架构已成为构建高可扩展、高可用系统的标准方法,广泛应用于电商、金融和物联网等领域。Java凭借其成熟的生态系统、强大的并发支持和跨平台能力,是微服务开发的首选语言。例如,我们的订单…

文件读取漏洞路径与防御总结

文件读取漏洞路径与防御总结 文件读取漏洞允许攻击者通过路径遍历等手段访问未授权的文件。以下是Linux和Windows系统中常见敏感路径的归纳及防御建议: Linux 系统常见敏感路径 系统关键文件: /etc/passwd:用户账户信息(可被用来…

react-router基本写法

1. 创建项目并安装所有依赖 npx create-react-app react-router-pro npm i 2. 安装所有的 react router 包 npm i react-router-dom 3. 启动项目 npm run start router/index.js // 创建路由实例 绑定path elementimport Layout from "/pages/Layout"; import…

uni-app 开发HarmonyOS的鸿蒙影视项目分享:从实战案例到开源后台

最近,HBuilderX 新版本发布,带来了令人兴奋的消息——uni-app 现在支持 Harmony Next 平台的 App 开发。这对于开发者来说无疑是一个巨大的福音,意味着使用熟悉的 Vue 3 语法和开发框架,就可以为鸿蒙生态贡献自己的力量。 前言 作…

纯css实现蜂窝效果

<!DOCTYPE html><html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>蜂窝效果</title><style>body {margin: 0…

JAVA EE_HTTP

为什么意气风发的少年&#xff0c;总是听不进去别人的劝解。 ​​​​​​​ ​​​​​​​ ----------陳長生. ❀主页&#xff1a;陳長生.-CSDN博客❀ &#x1f4d5;上一篇&#xff1a;JAVA EE_网络原理_数据链路层-CSDN博客 1.HTTP 1.1.HTTP是什么 H…

存储扇区分配表:NAND Flash与SD NAND(贴片式SD卡)的架构差异

NAND Flash 和 SD 卡&#xff08;SD NAND&#xff09;的存储扇区分配表在原理上有相似之处&#xff0c;但由于二者的结构和应用场景不同&#xff0c;也存在一些差异。 相同点&#xff1a; 基本功能&#xff1a;NAND Flash 和 SD 卡&#xff08;SD NAND&#xff09;的存储扇区分…

界面控件DevExpress WinForms中文教程:Banded Grid View - API

DevExpress WinForms拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用的应用程序&#xff0c;无论是Office风格的界面&#xff0c;还是分析处理大批量的业务数据&#xff0c;它都能轻松胜…

4G物联网模块实现废气处理全流程数据可视化监控配置

一、项目背景 随着工业化进程的加速&#xff0c;工业废气的排放对环境造成了严重影响&#xff0c;废气处理厂应运而生。然而&#xff0c;废气处理厂中的设备众多且分散&#xff0c;传统的人工巡检和数据记录方式效率低下&#xff0c;难以及时发现问题。为了实现对废气处理设备…

Kubernetes控制平面组件:Kubelet详解(四):gRPC 与 CRI gRPC实现

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes控…

【数据结构】线性表--队列

【数据结构】线性表--队列 一.什么是队列二.队列的实现1.队列结构定义&#xff1a;2.队列初始化函数&#xff1a;3.队列销毁函数&#xff1a;4.入队列函数&#xff08;尾插&#xff09;&#xff1a;5.出队列函数&#xff08;头删&#xff09;&#xff1a;6.取队头元素&#xff…

C语言—再学习(结构体)

一、建立结构体 用户自己建立由不同类型数据组成的组合型的数据结构&#xff0c;它称为结构体。 struct Student { int num; //学号char name[20]; //名字为字符串char sex; //性别int age; //年纪float score; //分数char addr[30]; 地址为字符…

【前端基础】10、CSS的伪元素(::first-line、::first-letter、::before、::after)【注:极简描述】

一、伪元素的作用 选取某个特定的元素。 二、::first-line、::first-letter ::first-line&#xff1a;针对首行文本设置属性 ::first-letter&#xff1a;针对首字母设置属性 三、::before、::after 在一个元素之前&#xff08;::before&#xff09;或者之后&#xff08;…

系统漏洞扫描服务:维护网络安全的关键与服务原理?

系统漏洞扫描服务是维护网络安全的关键措施&#xff0c;能够迅速发现系统中的潜在风险&#xff0c;有效预防可能的风险和损失。面对网络攻击手段的日益复杂化&#xff0c;这一服务的重要性日益显著。 服务原理 系统漏洞扫描服务犹如一名恪尽职守的安全守护者。它运用各类扫描…

从 Excel 到 Data.olllo:数据分析师的提效之路

背景&#xff1a;Excel 的能力边界 对许多数据分析师而言&#xff0c;Excel 是入门数据处理的第一工具。然而&#xff0c;随着业务数据量的增长&#xff0c;Excel 的一些固有限制逐渐显现&#xff1a; 操作容易出错&#xff0c;难以审计&#xff1b; 打开或操作百万行数据时&…

框架的源码理解——V3中的ref和reactive

最近在研究各个框架的源码&#xff0c;从源码角度去理解 vue3 的 reactive 和 ref API&#xff0c;记录下研究的成果 reactive 首先&#xff0c;reactive() 的参数必须是一个对象&#xff0c;返回值是一个 Proxy 对象&#xff0c;具有响应性。如果参数不是对象类型&#xff0…

能源数字化转型关键引擎:Profinet转Modbus TCP网关驱动设备协同升级

在工业自动化的世界中&#xff0c;ModbusTCP和Profinet是两个非常重要的通讯协议。ModbusTCP以其开放性和易用性&#xff0c;被广泛应用于各种工业设备中&#xff1b;而Profinet则以其高效性和实时性&#xff0c;成为了众多高端设备的首选。然而&#xff0c;由于这两种协议的差…