如何优化因为高亮造成的大文本(大字段)检索缓慢问题

首先还是说一下背景,工作中用到了 elasticsearch 的检索以及高亮展示,但是索引中的content字段是读取的大文本内容,所以后果就是索引的单个字段很大,造成单独检索请求的时候速度还可以,但是加入高亮之后检索请求的耗时就非常的慢了。所以本文从更换高亮器类型的角度来解决因为高亮造成的检索请求缓慢的问题。

ES的抵消策略

在文章开始前先简单介绍一个elasticsearch的策略,为了在检索的字段中创建出一个有意义的高亮片段,高亮器会使用原始文本的开始和结束字符串的偏移量,偏移量的获取可以从一下方式获得

  • postings list:如果在mappingindex_options设置为offsetsunified高亮器使用此信息高亮显示文档而不用再次分析文本。
  • term vectors:如果我们在mapping中设置term_vectorwith_positions_offsets,则unified高亮器会自动使用term_vector来高亮显示,对于大于1M的大字段,使用term_vector速度会很快,fvh高亮器就是使用的term_vector
  • plain highlighting:当unified没有其他的选择的时候会使用plain模式,它会创建了一个微小的内存索引,并通过Lucene的查询执行计划器重新运行原始查询条件。plain高亮器默认使用的就是此模式

大文本的纯高亮展示可能需要大量的时间和内存,为了防止这种情况,es默认将大文本的字符数量限制为1000000,可以使用index.highlight.max_analyzed_offset修改此默认设置

一、FVH高亮器简介

FVH(Fast Vector Highlighter)是Elasticsearch高亮器中的一种算法,使用的是Lucene Fast Vector highlighter,它能够快速而准确地在文本中找到匹配的关键词,并将其标记为高亮。相比于其他高亮器算法,FVH在性能上有着显著的优势,特别适用于大规模数据集和高并发的场景。

二、FVH高亮器的使用方法

安装

首先,确保已经正确安装了 Elasticsearch

version: '3.8'
services:cerebro:image: lmenezes/cerebro:0.8.3container_name: cerebroports:- "9000:9000"command:- -Dhosts.0.host=http://eshot:9200networks:- elastickibana:image: docker.elastic.co/kibana/kibana:8.1.3container_name: kibanaenvironment:- I18N_LOCALE=zh-CN- XPACK_GRAPH_ENABLED=true- TIMELION_ENABLED=true- XPACK_MONITORING_COLLECTION_ENABLED="true"- ELASTICSEARCH_HOSTS=http://eshot:9200- server.publicBaseUrl=http://192.168.160.234:5601ports:- "5601:5601"networks:- elasticeshot:image: elasticsearch:8.1.3container_name: eshotenvironment:- node.name=eshot- cluster.name=es-docker-cluster- discovery.seed_hosts=eshot,eswarm,escold- cluster.initial_master_nodes=eshot,eswarm,escold- bootstrap.memory_lock=true- "ES_JAVA_OPTS=-Xms512m -Xmx512m"- xpack.security.enabled=false- node.attr.node_type=hotulimits:memlock:soft: -1hard: -1volumes:- D:\zuiyuftp\docker\es8.1\eshot\data:/usr/share/elasticsearch/data- D:\zuiyuftp\docker\es8.1\eshot\logs:/usr/share/elasticsearch/logs- D:\zuiyuftp\docker\es8.1\eshot\plugins:/usr/share/elasticsearch/pluginsports:- 9200:9200networks:- elasticeswarm:image: elasticsearch:8.1.3container_name: eswarmenvironment:- node.name=eswarm- cluster.name=es-docker-cluster- discovery.seed_hosts=eshot,eswarm,escold- cluster.initial_master_nodes=eshot,eswarm,escold- bootstrap.memory_lock=true- "ES_JAVA_OPTS=-Xms512m -Xmx512m"- xpack.security.enabled=false- node.attr.node_type=warmulimits:memlock:soft: -1hard: -1volumes:- D:\zuiyuftp\docker\es8.1\eswarm\data:/usr/share/elasticsearch/data- D:\zuiyuftp\docker\es8.1\eswarm\logs:/usr/share/elasticsearch/logs- D:\zuiyuftp\docker\es8.1\eshot\plugins:/usr/share/elasticsearch/pluginsnetworks:- elasticescold:image: elasticsearch:8.1.3container_name: escoldenvironment:- node.name=escold- cluster.name=es-docker-cluster- discovery.seed_hosts=eshot,eswarm,escold- cluster.initial_master_nodes=eshot,eswarm,escold- bootstrap.memory_lock=true- "ES_JAVA_OPTS=-Xms512m -Xmx512m"- xpack.security.enabled=false- node.attr.node_type=coldulimits:memlock:soft: -1hard: -1volumes:- D:\zuiyuftp\docker\es8.1\escold\data:/usr/share/elasticsearch/data- D:\zuiyuftp\docker\es8.1\escold\logs:/usr/share/elasticsearch/logs- D:\zuiyuftp\docker\es8.1\eshot\plugins:/usr/share/elasticsearch/pluginsnetworks:- elastic# volumes:
#   eshotdata:
#     driver: local
#   eswarmdata:
#     driver: local
#   escolddata:
#     driver: localnetworks:elastic:driver: bridge

创建索引

在使用FVH高亮器之前,需要先创建一个索引,并将需要高亮的字段进行映射。例如,我们要在content字段中进行高亮,可以使用以下代码:

PUT /example_target
{"mappings": {"properties": {"content": {"type": "text","analyzer": "ik_max_word","term_vector": "with_positions_offsets"},"title": {"type": "text","analyzer": "ik_max_word","term_vector": "with_positions_offsets"}}}
}

添加测试数据

POST example_target/_doc
{"content":"中华人民共和国是否考虑是否就爱上速度加快分解ask计算机卡死撒中华上的飞机拉丝机是的地方记录 卡就是开发建设看积分卡说了句 ask就疯狂萨拉丁就发士大 sdf 看得见啊李开复 圣诞节卡了 夫哈数据库中华啊,中华,人民爱上中华","title":"中华人名共和国"
}

查询并高亮

使用FVH高亮器进行查询和高亮的过程如下所示:

GET example_target/_search
{"query": {"match": {"content": "中华 爱上"}},"highlight": {"pre_tags": "<em>","post_tags": "</em>", "require_field_match": "false", "fields": {"content": {"type": "fvh","fragment_size": 18,"number_of_fragments": 3}}}
}

以上代码中,我们通过match查询找到了包含关键词的文档,然后在highlight内容中指定了需要高亮的字段,这里是content。执行述查询后,Elasticsearch将返回匹配的结果,并在content字段中添加了高亮标记。

数据量少的时候对比不是特别明显,所以在测试时,可以在索引中添加大量的测试数据进行测试,本人在测试过程中es的索引大小在500M左右,单个字段纯文本大小也有1-2M。此时这种数据规模下使用普通的高亮器在检索请求时就已经非常缓慢了,根据返回的数据量多少来决定,在取10条数据时已经能达到6秒了,但是在使用fvh高亮器之后时间已经进入毫秒级

三、FVH高亮器的参数配置

先看一下返回的数据结果在对照下面参数学习

{"took" : 4,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 3,"relation" : "eq"},"max_score" : 0.41193593,"hits" : [{"_index" : "example_target","_id" : "f1rkC4oBCDmhQc2yo6PQ","_score" : 0.41193593,"_source" : {"content" : "中华人民共和国是否考虑是否就爱上速度加快分解ask计算机卡死撒中华上的飞机拉丝机是的地方记录 卡就是开发建设看积分卡说了句 ask就疯狂萨拉丁就发士大 sdf 看得见啊李开复 圣诞节卡了 夫哈数据库中华啊,中华,人民爱上中华"},"highlight" : {"content" : ["<em>中华</em>人民共和国是否考虑是否就<em>爱上</em>速度","sk计算机卡死撒<em>中华</em>上的飞机拉丝机是的地方记录","夫哈数据库<em>中华</em>啊,<em>中华</em>,人民<em>爱上</em>中华"]}},{"_index" : "example_target","_id" : "G3Fi44kB4IVEhjafHXOf","_score" : 0.33311102,"_source" : {"content" : "中华人民共和国是否考虑是否就爱上速度加快分解ask计算机卡死撒中华上的飞机拉丝机是的地方记录卡就是开发建设看积分卡说了句ask就疯狂萨拉丁就发士大夫哈数据库"},"highlight" : {"content" : ["<em>中华</em>人民共和国是否考虑是否就<em>爱上</em>速度","sk计算机卡死撒<em>中华</em>上的飞机拉丝机是"]}},{"_index" : "example_target","_id" : "HHFt44kB4IVEhjafE3Ov","_score" : 0.31932122,"_source" : {"content" : "中华人民共和国是否考虑是否就爱上速度加快分解ask计算机卡死撒中华上的飞机拉丝机是的地方记录 卡就是开发建设看积分卡说了句 ask就疯狂萨拉丁就发士大 sdf 看得见啊李开复 圣诞节卡了 夫哈数据库"},"highlight" : {"content" : ["<em>中华</em>人民共和国是否考虑是否就<em>爱上</em>速度","sk计算机卡死撒<em>中华</em>上的飞机拉丝机是的地方记录"]}}]}
}

通过上面的查询请求中高亮参数的指定可以发现,高亮器还是支持其他的参数的,那么我们下面将对几个常用的参数进行说明

  • fragment_size:指定每个高亮片段的长度,默认为100个字符。

  • number_of_fragments:指定返回的高亮片段数量,默认为5个。

  • pre_tagspost_tags:分别指定高亮标记的前缀和后缀,默认为<em></em>

  • require_field_match:指定是否要求所有字段都匹配关键词才进行高亮,默认为true。可以开启关闭此参数对上面的title字段进行校验

  • type:指定fvh高亮器,除了fvh之外还有unifiedplain

    • unified 是默认的高亮器,可以将文本分解为句子,并使用BM25算法对单个句子进行评分,还支持精确的短语高亮显示,支持(fuzzyprefixregex)高亮。
    • plain 普通的高亮器,适用与简单的查询或者单个字段的匹配。为了准确的反应查询逻辑,它会在内存中创建一个很小的索引,来对原始的查询语句进行执行,来访问当前更低级别的匹配信息。

在使用FVH高亮器时,根据实际需求,可以灵活地调整这些参数,以获得最佳的高亮效果。

总结

通过本文的介绍,我们了解了Elasticsearch高亮器中的FVH算法,并学会了如何使用它为搜索结果增添亮点。FVH高亮器在性能和功能上都有着明显的优势,对于大规模数据集和高并发的场景尤为适用。希望读者通过本文的指引,能够更好地利用FVH高亮器来提升搜索结果的可读性和用户体验。

参考链接

https://www.elastic.co/guide/en/elasticsearch/reference/8.1/highlighting.html

如果感觉本文对你有所帮助欢迎点赞评论转发收藏。如果你想了解更多关于ES的骚操作,更多实战经验,欢迎关注。

原文链接
https://mp.weixin.qq.com/s?__biz=MzIwNzYzODIxMw==&mid=2247486065&idx=1&sn=28ee03fd0e297eb0c5d62405446d4551&chksm=970e11dba07998cd53a3a16e39e396172c3e3b46f96bab0e097eeab08fefb93c63b0d48fe380#rd

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

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

相关文章

开始MySQL之路——MySQL约束概述详解

MySQL约束 create table [if not exists] 表名(字段名1 类型[(宽度)] [约束条件] [comment 字段说明],字段名2 类型[(宽度)] [约束条件] [comment 字段说明],字段名3 类型[(宽度)] [约束条件] [comment 字段说明] )[表的一些设置]; 概念 约束英文&#xff1a;constraint 约束实…

GeoHash之存储篇

前言&#xff1a; 在上一篇文章GeoHash——滴滴打车如何找出方圆一千米内的乘客主要介绍了GeoHash的应用是如何的&#xff0c;本篇文章我想要带大家探索一下使用什么样的数据结构去存储这些Base32编码的经纬度能够节省内存并且提高查询的效率。 前缀树、跳表介绍&#xff1a; …

数据结构队列的实现

本章介绍数据结构队列的内容&#xff0c;我们会从队列的定义以及使用和OJ题来了解队列&#xff0c;话不多说&#xff0c;我们来实现吧 队列 1。队列的概念及结构 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;…

centos7搭建apache作为文件站后,其他人无法访问解决办法

在公司内网的一个虚拟机上搭建了httpsd服务&#xff0c;准备作为内部小伙伴们的文件站&#xff0c;但是搭建好之后发现别的小伙伴是无法访问我机器的。 于是寻找一下原因&#xff0c;排查步骤如下&#xff1a; 1.netstat -lnp 和 ps aux 先看下端口和 服务情况 发现均正常 2.…

设计模式-工厂设计模式

核心思想 在简单工厂模式的基础上进一步的抽象化具备更多的可扩展和复用性&#xff0c;增强代码的可读性使添加产品不需要修改原来的代码&#xff0c;满足开闭原则 优缺点 优点 符合单一职责&#xff0c;每个工厂只负责生产对应的产品符合开闭原则&#xff0c;添加产品只需添…

探讨uniapp的路由与页面生命周期问题

1 首先我们引入页面路由 2 页面生命周期函数 onLoad() {console.log(页面加载)},onShow() {console.log(页面显示)},onReady(){console.log(页面初次显示)},onHide() {console.log(页面隐藏)},onUnload() {console.log(页面卸载)},onBackPress(){console.log(页面返回)}3 页面…

代码随想录算法训练营之JAVA|第三十九天|474. 一和零

今天是第39天刷leetcode&#xff0c;立个flag&#xff0c;打卡60天。 算法挑战链接 474. 一和零https://leetcode.cn/problems/ones-and-zeroes/ 第一想法 题目理解&#xff1a;找到符合条件的子集&#xff0c;这又是一个组合的问题。 看到这个题目的时候&#xff0c;我好像…

JAVA学习-愚见

JAVA学习-愚见 分享一下Java的学习路线&#xff0c;仅供参考【本人亲测&#xff0c;真实有效】 1、尽可能推荐较新的课程 2、大部分视频在B站上直接搜关键词就行【自学&#xff0c;B大的学生】 文章目录 JAVA学习-愚见前期准备Java基础课程练手项目 数据库JavaWeb前端基础 Vue…

学习设计模式之观察者模式,但是宝可梦

前言 作者在准备秋招中&#xff0c;学习设计模式&#xff0c;做点小笔记&#xff0c;用宝可梦为场景举例&#xff0c;有错误欢迎指出。 观察者模式 观察者模式定义了一种一对多的依赖关系&#xff0c;一个对象的状态改变&#xff0c;其他所有依赖者都会接收相应的通知。 所…

匈牙利算法 in 二分图匹配

https://www.luogu.com.cn/problem/P3386 重新看这个算法&#xff0c;才发现自己没有理解。 左边的点轮流匹配&#xff0c;看是否能匹配成功。对右边的点进行记录是否尝试过 然后有空就进&#xff0c;别人能退的就进 遍历左部点&#xff1a; 尝试匹配过程&#xff1a;

[C++] STL_vector 迭代器失效问题

文章目录 1、前言2、情况一&#xff1a;底层空间改变的操作3、情况二&#xff1a;指定位置元素的删除操作4、g编译器对迭代器失效检测4.1 扩容4.2 erase删除任意位置&#xff08;非尾删&#xff09;4.3 erase尾删 5、总结 1、前言 **迭代器的主要作用就是让算法能够不用关心底…

DataWhale 机器学习夏令营第三期——任务二:可视化分析

DataWhale 机器学习夏令营第三期 学习记录二 (2023.08.23)——可视化分析1.赛题理解2. 数据可视化分析2.1 用户维度特征分布分析2.2 时间特征分布分析 DataWhale 机器学习夏令营第三期 ——用户新增预测挑战赛 学习记录二 (2023.08.23)——可视化分析 2023.08.17 已跑通baseli…

Android沉浸式实现(记录)

沉浸式先看效果 直接上代码 Android manifest文件 android:theme"style/Theme.AppCompat.NoActionBar"布局文件 <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"ht…

mit s0681 lab2 Trace系统调用实现

实验一 实现一个用户级别的程序&#xff0c;功能为&#xff0c;指定系统调用后&#xff0c;跟踪程序的系统调用情况 分析实验 实验目标为实现一个程序去跟踪指定程序的系统调用。因此目标有两个 实现一个程序跟踪目标程序的系统调用 实现1&#xff0c;就需要在用户这边实…

4.18 TCP 和 UDP 可以使用同一个端口吗?

目录 TCP 和 UDP 可以同时绑定相同的端口吗&#xff1f; 多个 TCP 服务进程可以绑定同一个端口吗&#xff1f; 重启 TCP 服务进程时&#xff0c;为什么会有“Address in use”的报错信息&#xff1f; 重启 TCP 服务进程时&#xff0c;如何避免“Address in use”的报错信息…

HarmonyOS/OpenHarmony应用开发-ArkTS语言渲染控制LazyForEach数据懒加载

LazyForEach从提供的数据源中按需迭代数据&#xff0c;并在每次迭代过程中创建相应的组件。当LazyForEach在滚动容器中使用了&#xff0c;框架会根据滚动容器可视区域按需创建组件&#xff0c;当组件划出可视区域外时&#xff0c;框架会进行组件销毁回收以降低内存占用。一、接…

智驾算力芯片市场仍处于「波动」周期,Momenta曝光自研NPU

用「冷热不均」来形容当下的汽车芯片赛道&#xff0c;再合适不过了。 本周&#xff0c;英伟达公布的第二财季&#xff08;5-7月&#xff09;营收达到创纪录的135亿美元&#xff0c;大幅超出了此前市场普遍预期的略高于110亿美元&#xff0c;同比增速更是达到了101%。 其中&…

接口测试总结分享(http与rpc)

接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换&#xff0c;传递和控制管理过程&#xff0c;以及系统间的相互逻辑依赖关系等。 一、了解一下HTTP与RPC 1. HTTP&#xff08;H…

【python】输出高亮信息的内容

背景 日志是定位问题和数据分析的关键手段之一&#xff0c;尤其是在调试阶段&#xff0c;高效的、具有辨识度的日志可以非常快速准确的进行问题定位。shell中的echo命令自带文本格式化输出的功能&#xff0c;我们先来回顾下基本的语法&#xff0c;然后套用到python中即可。 s…

Docker安装及Docker构建简易版Hadoop生态

一、首先在VM创建一个新的虚拟机将Docker安装好 更新系统&#xff1a;首先打开终端&#xff0c;更新系统包列表。 sudo apt-get update sudo apt-get upgrade下图是更新系统包截图 安装Docker&#xff1a;使用以下命令在Linux上安装Docker。 sudo apt-get install -y docker.i…