Elasticsearch:使用 semantic_text 简化语义搜索
作者:来自 Elastic Carlos Delgado, Mike Pellegrini
semantic_text - 你知道,用于语义搜索!
你是否想开始使用语义搜索来搜索数据,但专注于模型和结果而不是技术细节?我们引入了 semantic_text 字段类型,它将处理你所需的细节和基础架构。
语义搜索(semantic search)是一种复杂的技术,旨在通过利用机器学习模型来增强搜索结果的相关性。与传统的基于关键字的搜索不同,语义搜索专注于理解单词的含义及其使用的上下文。这是通过应用机器学习模型来实现的,这些模型可以提供对文本的更深入的语义理解。
这些模型生成向量嵌入(vector embeddings),它们是捕获文本含义的数字表示。这些嵌入与你的文档数据一起存储,从而启用考虑单词含义和上下文而不是纯词汇匹配的向量搜索技术。
你需要添加什么来添加语义搜索?
要执行语义搜索,你需要执行以下步骤:
- 选择一个推理模型来创建嵌入,用于索引文档和执行查询。
- 创建索引映射以存储推理结果,以便之后可以有效地搜索它们。
- 设置索引,以便为添加到索引中的新文档计算推理结果。
- 自动处理长文本文档,以便搜索准确并覆盖整个文档。
- 查询数据以检索结果。
从头开始配置语义搜索可能很复杂。它需要设置映射、提取管道和针对你选择的推理模型量身定制的查询。每个步骤都提供了微调和优化的机会,但也需要仔细配置以确保所有组件无缝协作。
虽然这提供了很大程度的控制,但它使使用语义搜索成为一个详细而深思熟虑的过程,要求你配置彼此相关并与推理模型相关的单独部分。
semantic_text 通过专注于重要的事情来简化此过程:推理模型。一旦你选择了推理模型,semantic_text 将通过提供合理的默认值让你轻松开始使用语义搜索,这样你就可以专注于搜索,而不是如何索引、生成或查询嵌入。
让我们看一下每个步骤,以及 semantic_text 如何简化此设置。
选择一个推理模型
推理模型将为你的文档和查询生成嵌入。不同的模型在以下方面有不同的权衡:
- 结果的准确性和相关性
- 可扩展性和性能
- 语言和多语言支持
- 成本
Elasticsearch 支持内部和外部推理服务:
- 内部服务部署在 Elasticsearch 集群中。你可以使用已包含的模型(如 ELSER 和 E5),也可以使用 eland 将外部模型导入集群。
- 外部服务由模型提供商部署。Elasticsearch 支持以下内容:
- Cohere
- Hugging Face
- Mistral
- OpenAI
- Azure AI Studio
- Azure OpenAI
- Google AI Studio
选择推理模式后,为其创建推理端点。推理端点标识符将是你设置 semantic_text 所需的唯一配置详细信息。
PUT _inference/sparse_embedding/my-elser-endpoint
{ "service": "elser", "service_settings": { "num_allocations": 1, "num_threads": 1 } }
创建索引映射
Elasticsearch 需要对模型生成的嵌入进行索引,以便以后可以有效地查询它们。
在使用 semantic_text 之前,你需要了解用于存储嵌入信息的两个主要字段类型:
- sparse_vector:它对稀疏向量嵌入进行索引,例如 ELSER 生成的嵌入。每个嵌入都由标记和权重对组成。每个嵌入都会生成少量标记。
- dense_vector:它对包含嵌入信息的数字向量进行索引。模型会生成固定大小的向量,称为向量维度。
要使用的字段类型取决于你选择的模型。如果使用密集向量,你需要配置字段以包含维度计数、用于计算向量接近度的相似度函数以及存储自定义,例如量化或每个元素使用的特定数据类型。
现在,如果你使用 semantic_text,则只需为模型指定推理端点标识符即可定义 semantic_text 字段映射:
PUT test-index
{ "mappings": { "properties": { "infer_field": { "type": "semantic_text", "inference_id": "my-elser-endpoint" } } } }
就是这样。你无需定义其他映射选项,也无需了解需要使用哪种字段类型。
设置索引
一旦你的索引准备好存储嵌入,就该生成它们了。
在 semantic_text 之前,要自动在文档摄取时生成嵌入,你需要设置摄取管道。
摄取管道用于在摄取到索引中时或在摄取过程中明确指定时自动丰富或转换文档。
你需要使用 inference processor 为你的字段生成嵌入。处理器需要使用以下内容进行配置:
- 从中生成嵌入的文本字段
- 将添加生成的嵌入的输出字段
- 根据模型类型,针对文本嵌入或稀疏嵌入的特定推理配置
使用 semantic_text,你只需将文档添加到索引中。semantic_text 字段将使用指定的推理端点自动计算嵌入。
这意味着无需创建推理管道来生成嵌入。使用批量、索引或更新 API 将自动为你执行此操作:
PUT test-index/_doc/doc1
{ "infer_field": "These are not the droids you're looking for. He's free to go around" }
semantic_text 字段中的推理请求也是批量处理的。如果你在 bulk API 请求中有 10 个文档,并且每个文档包含 2 个 semantic_text 字段,那么该请求将一次性向你的推理服务执行包含 20 个文本的单个推理请求,而不是每次发出 10 个包含 2 个文本的单独推理请求。
自动处理长文本段落
选择模型的挑战之一是模型可以生成嵌入的标记数量。模型可以处理的标记数量有限。这被称为模型的上下文窗口。
如果你需要处理的文本比模型的上下文窗口长,你可以截断文本并仅使用其中的一部分来生成嵌入。这并不理想,因为你会丢失信息;生成的嵌入将无法捕获输入文本的完整上下文。
即使你有一个长的上下文窗口,长文本也意味着大量内容将被缩减为单个嵌入,从而使其成为不准确的表示。
此外,返回长文本会让用户难以理解,因为他们必须扫描文本以检查它是否是他们要查找的内容。最好使用较小的片段。
另一种选择是使用分块将长文本分成较小的片段。这些较小的块被添加到每个文档中,以更好地表示完整的文本。然后,你可以使用嵌套查询搜索所有单个片段并检索包含得分最高的块的文档。
在 semantic_text 之前,分块不是开箱即用的 - 推理处理器不支持分块。如果你需要使用分块,则需要在提取文档之前进行分块,或者使用脚本处理器在 Elasticsearch 中执行分块。
使用 semantic_text 意味着在索引时将为你完成分块。长文档将被拆分为 250 个单词的部分,其中有 100 个单词重叠,因此每个部分与前一个部分共享 100 个单词。这种重叠可确保连续性,并防止输入文本中的重要上下文信息因硬中断而丢失。
如果模型和推理服务支持批处理,则分块输入会自动批处理为尽可能少的请求,每个请求的大小都适合推理服务。生成的块将存储在嵌套对象结构中,以便你可以检查每个块中包含的文本。
查询数据
现在文档及其嵌入已在 Elasticsearch 中编入索引,是时候进行一些查询了!
在使用 semantic_text 之前,你需要根据模型生成的嵌入类型(密集或稀疏)使用不同的查询。查询 sparse_vector 字段类型需要 sparse vector query,而搜索 density_vector 字段类型则可以使用 knn search 或 knn query。
查询过程可以进一步定制,以提高性能和相关性。例如,稀疏向量查询可以定义标记修剪(token pruning),以避免考虑不相关的标记。Knn 查询可以指定要考虑的候选数以及要从每个分片返回的前 k 个结果。
使用 semantic_text 时,你无需处理这些细节。你可以使用 single query type 来搜索文档:
GET test-index/_search
{ "query": { "semantic": { "field": "inference_field", "query": "robots you're searching for" } } }
只需包含字段和查询文本。无需在稀疏向量和 knn 查询之间做出选择,语义文本会为你完成此操作。
将其与使用具有所有配置参数的特定 knn 搜索进行比较:
{ "knn": { "field": "inference-field", "k": 10, "num_candidates": 100, "query_vector_builder": { "text_embedding": { "model_id": "my-dense-vector-embedding-model", "model_text": "robots you're searching for" } } } }
底层原理
要了解 semantic_text 的工作原理,你可以创建一个 semantic_text 索引并检查摄取文档时会发生什么。摄取第一个文档时,推理端点会计算嵌入。索引后,你会注意到索引映射中的变化:
GET test-index
{ "test-index": { "mappings": { "properties": { "infer_field": { "type": "semantic_text", "inference_id": "my-elser-endpoint", "model_settings": { "task_type": "sparse_embedding" } } } } } }
现在有关于模型设置的附加信息。文本嵌入模型还将包括模型的维度数或相似度函数等信息。
你可以检查文档是否已包含嵌入结果:
GET test-index/_doc/doc1
{ "_index": "test-sparse", "_id": "doc1", "_source": { "infer_field": { "text": "these are not the droids you're looking for. He's free to go around", "inference": { "inference_id": "my-elser-endpoint", "model_settings": { "task_type": "sparse_embedding" }, "chunks": [ { "text": "these are not the droids you're looking for. He's free to go around", "embeddings": { "##oid": 1.9103845, "##oids": 1.768872, "free": 1.693662, "dr": 1.6103356, "around": 1.4376559, "these": 1.1396849 … } } ] } } } }
该字段不仅包含输入文本,还包含一个结构,用于存储原始文本、模型设置以及输入文本被划分成的每个块的信息。
此结构由一个具有两个元素的对象组成:
- text:包含原始输入文本
- inference:推理端点添加的推理信息,包括:
- 推理端点的 inference_id
- 包含模型属性的 model_settings
- chunks:嵌套对象,包含从输入文本创建的每个块的元素。每个块包含:
- 块的 text
- 块文本的计算 embeddings
自定义语义文本
semantic_text 通过对数据进行索引和查询做出默认决策来简化语义搜索:
- 根据推理模型类型使用 sparse_vector 或 density_vector 字段类型
- 根据推理结果自动定义维度数和相似度
- 对密集向量字段类型使用 int8_hnsw 索引类型来利用标量量化 。
- 使用查询默认值。sparse_vector 查询不应用任何标记修剪,knn 查询也不设置自定义 k 和 num_candidates。
这些都是合理的默认值,可让你快速轻松地开始使用语义搜索。随着时间的推移,你可能希望自定义查询和数据类型以优化搜索相关性、索引和查询性能以及索引存储。
查询自定义
目前还没有针对语义查询的自定义选项。如果你想针对 semantic_text 字段自定义查询,可以使用显式 knn 和稀疏向量查询执行高级 semantic_text 搜索。
我们计划添加对 semantic_text 的 retrievers 支持,并向 semantic_text 字段添加配置选项,以便在查询时不需要它们。敬请期待!
数据类型自定义
如果你需要对数据索引进行更深入的自定义,则可以使用 sparse_vector 或 density_vector 字段类型。这些字段类型让你可以完全控制嵌入的生成、索引和查询方式。
你需要创建一个带有推理处理器的摄取管道来生成嵌入。本教程将引导你完成整个过程。
下一步是什么?
我们刚刚开始使用 semantic_text!我们将继续致力于许多增强功能,包括:
- 更好的推理错误处理
- 自定义分块策略
- 默认隐藏 _source 中的嵌入,以避免使搜索响应混乱
- 内部命中支持,用于检索查询的相关信息块
- 过滤和 retrievers 支持
- Kibana 支持
试试吧!
使用此笔记本[准备好后添加链接]探索语义文本,快速了解语义文本的工作原理。
如果你已经拥有 Elasticsearch 集群,则可以在本教程中查看使用语义文本测试语义搜索的完整示例。
我们很乐意听听你使用语义文本的经验!请在论坛中告诉我们你的想法,或在 GitHub 存储库中打开问题。让我们一起让语义搜索更容易!
准备好自己尝试一下了吗?开始免费试用。
Elasticsearch 集成了 LangChain、Cohere 等工具。加入我们的高级语义搜索网络研讨会,构建你的下一个 GenAI 应用程序!
原文:Semantic search simplified with semantic_text — Elastic Search Labs

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
MongoPlus 2.1.0 更新,多租户、数据变动记录、字段脱敏加解密等等功能来了!
简介 MongoPlus是一个基于MongoDB官方驱动,可以像MyBatisPlus一样优雅的操作MongoDB的ORM框架;旨在简化开发、降低学习成本 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作 强大的 CRUD 操作:通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错 支持主键自动生成:支持多达 5 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题 支持无实体类情况下的操作 支持动态数据源 支持逻辑删除、防止全集合更新和删除、自动填充等等功能 官网:https://www.mongoplus.com Gitee:https://gitee.com/aizuda/mongo-plus GitHub: https://github.com/anwena/MongoPlus 版本 最...
- 下一篇
数据特征采样在 MySQL 同步一致性校验中的实践
作者:vivo 互联网存储研发团队 - Shang Yongxing 本文介绍了当前DTS应用中,MySQL数据同步使用到的数据一致性校验工具,并对它的实现思路进行分享。 一、背景 在 MySQL 的使用过程中,经常会因为如集群拆分、数据传输、数据聚合等原因产生流动和数据复制。而在通常的数据复制过程中,因为涉及到目标的写入不可控、服务应用的未知问题、人为导致的异常缺陷等,很难保证复制产生的数据与源完全一致。除了通过完善流程与服务应用的能力和可靠性来保障数据一致性外,也需要提供快速有效的数据校验机制,便于发现存在异常的数据位置,服务于后续可能的自动重试或人工修订。 而具体到我们目前使用的数据传输服务DTS(MySQL部分),需要考虑的点: 端对端从源集群到目标集群的外部数据校验 内部数据校验机制,确保同步的数据正确可靠 二、选型参考 数据一致性校验,即对DTS的数据同步任务在目标产生(复制)的表数据,与在源库的原始数据进行对比,并给出对比结果。若存在不一致的情况则给出具体不一致的数据块,方便用户快速对不一致数据进行处理。它的基本原则是作为独立一个环节,既不能影响同步本身,也不能影响业务数...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2全家桶,快速入门学习开发网站教程
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- 2048小游戏-低调大师作品
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS6,CentOS7官方镜像安装Oracle11G