【Elasticsearch】高亮搜索:从原理到Web呈现
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c=1000,移动端可微信小程序搜索“历代文学”)总架构师,
15年
工作经验,精通Java编程
,高并发设计
,Springboot和微服务
,熟悉Linux
,ESXI虚拟化
以及云原生Docker和K8s
,热衷于探索科技的边界,并将理论知识转化为实际应用。保持对新技术的好奇心,乐于分享所学,希望通过我的实践经历和见解,启发他人的创新思维。在这里,我希望能与志同道合的朋友交流探讨,共同进步,一起在技术的世界里不断学习成长。
技术合作请加本人wx(注明来自csdn):foreast_sea
【Elasticsearch】高亮搜索:从原理到Web呈现
一、引言
在当今的大数据时代,数据的高效搜索和精准呈现变得至关重要。Elasticsearch
作为一款强大的分布式搜索和分析引擎,被广泛应用于各种数据搜索场景。其中,高亮搜索是一个非常实用的功能,它能够在搜索结果中突出显示与查询关键词匹配的部分,大大提高了用户体验。
假设我们正在构建一个文档管理系统,用户输入关键词进行搜索时,我们希望不仅能找到相关文档,还能在文档的片段中清晰地显示出关键词所在的位置。这时候,Elasticsearch
的高亮搜索就派上了用场。例如,在一个包含大量技术文章的知识库中,用户搜索“Java并发编程”,高亮搜索可以在搜索到的文章摘要中,将“Java”和“并发编程”这几个字以特殊的样式(如加粗、变色等)显示出来,让用户一眼就能看到匹配的部分。
然而,要实现这样一个功能并非易事,它涉及到多个方面的知识和技术。我们需要了解Elasticsearch
的工作原理,特别是其高亮搜索的原理。同时,在Java开发中,我们要选择合适的Elasticsearch
客户端,构建正确的查询语句,发送请求到服务器,然后解析响应结果,最终在Web客户端中完美地呈现出来。这一系列的操作就像一个精密的链条,每个环节都紧密相连,任何一个环节出现问题都可能导致最终结果不理想。在接下来的文章中,我们将一步步深入探讨Elasticsearch Java
高亮搜索的各个环节,帮助读者全面掌握这一重要技术。
二、Elasticsearch高亮搜索原理
- 什么是高亮搜索
- 高亮搜索是一种在搜索结果中突出显示与查询关键词匹配部分的技术。在Elasticsearch中,它通过分析查询语句中的关键词,在搜索到的文档中找到这些关键词的位置,然后以特定的方式(如添加HTML标签)来标记这些位置,以便在显示结果时能够突出显示。
- 例如,当我们查询“elasticsearch性能优化”时,在搜索到的文档中,“elasticsearch”和“性能优化”这两个短语所在的部分会被特殊标记,这样用户可以很直观地看到搜索关键词在文档中的位置。
- 实现原理
- 分析查询:当我们发起一个包含高亮要求的搜索查询时,
Elasticsearch
首先会解析查询语句。它会确定查询中的关键词、查询类型(如模糊查询、精确查询等)以及其他相关的查询条件。 - 搜索文档:然后,
Elasticsearch
会根据查询条件在索引的文档中进行搜索。它会使用倒排索引等技术快速定位可能包含关键词的文档。 - 确定高亮片段:一旦找到匹配的文档,
Elasticsearch
会分析文档的内容,确定关键词在文档中的具体位置。它会根据预定义的规则(如前后多少个字符作为高亮片段)来选择要高亮显示的部分。 - 标记高亮:最后,
Elasticsearch
会使用特定的标记(如HTML标签)来标记高亮片段。例如,对于HTML呈现,可能会将关键词包裹在<strong>
标签中,这样在Web页面中就会以加粗的形式显示。
- 分析查询:当我们发起一个包含高亮要求的搜索查询时,
三、选择Elasticsearch客户端
- RestHighLevelClient
- 简介
- 在Java开发中,RestHighLevelClient是与Elasticsearch交互的常用客户端。它是Elasticsearch官方推荐的高级REST客户端,提供了方便的API来执行各种操作,包括搜索、索引创建、文档更新等。
- 它构建在较低级别的RestClient之上,隐藏了一些底层的HTTP请求细节,使得开发人员可以更专注于业务逻辑。
- Maven依赖
- 在Maven项目中,我们需要添加以下依赖:
- 简介
<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.17.9</version>
</dependency>
<dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.17.9</version>
</dependency>
<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId><version>7.17.9</version>
</dependency>
- 初始化客户端
- 以下是初始化RestHighLevelClient的示例代码:
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;public class ElasticsearchClientUtil {private static RestHighLevelClient client;public static RestHighLevelClient getClient() {if (client == null) {RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "http"));client = new RestHighLevelClient(builder);}return client;}public static void closeClient() {try {if (client!= null) {client.close();}} catch (IOException e) {e.printStackTrace();}}
}
- 对比其他客户端(可选)
- 除了
RestHighLevelClient
,还有TransportClient
等客户端。不过,TransportClient在Elasticsearch 7.0
之后已被标记为弃用,并且将在未来版本中被移除。RestHighLevelClient
具有更好的兼容性、易用性和性能,更适合现代的Elasticsearch
开发。
- 除了
四、添加高亮部分到查询语句
- 构建基本查询
- 在使用RestHighLevelClient进行搜索时,我们首先要构建一个基本的查询对象。例如,对于一个简单的关键词查询,我们可以使用
MatchQueryBuilder
。
- 在使用RestHighLevelClient进行搜索时,我们首先要构建一个基本的查询对象。例如,对于一个简单的关键词查询,我们可以使用
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("content", "elasticsearch");
- 这里的
matchQuery
方法接受两个参数,第一个参数是要查询的字段名(这里是content
字段),第二个参数是查询的关键词(这里是elasticsearch
)。
- 添加高亮设置
- 创建HighlightBuilder
- 要添加高亮部分,我们需要创建一个
HighlightBuilder
对象。
- 要添加高亮部分,我们需要创建一个
- 创建HighlightBuilder
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;HighlightBuilder highlightBuilder = new HighlightBuilder();
- 设置高亮字段
- 我们可以指定要高亮的字段,例如:
highlightBuilder.field("content");
- 设置高亮标签(可选)
- 如果我们想要自定义高亮的显示标签,比如使用
<em>
标签代替默认的<strong>
标签,我们可以这样设置:
- 如果我们想要自定义高亮的显示标签,比如使用
highlightBuilder.preTags("<em>");
highlightBuilder.postTags("</em>");
- 将高亮设置添加到查询
- 最后,我们将高亮设置添加到查询对象中。
matchQueryBuilder.highlighter(highlightBuilder);
五、发送高亮搜索请求到ES服务器
- 构建SearchRequest
- 我们需要构建一个
SearchRequest
对象来封装我们的搜索请求。
- 我们需要构建一个
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.Index;Index index = new Index("my_index", "_doc");
SearchRequest searchRequest = new SearchRequest(index);
searchRequest.source().query(matchQueryBuilder);
- 这里我们指定了要搜索的索引(
my_index
),并且将之前构建的包含高亮设置的查询对象(matchQueryBuilder
)添加到搜索请求中。
- 执行搜索请求
- 使用
RestHighLevelClient
来执行搜索请求。
- 使用
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;RestHighLevelClient client = ElasticsearchClientUtil.getClient();
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
- 这里我们调用
client.search
方法,传入SearchRequest
对象和默认的请求选项(RequestOptions.DEFAULT
),然后得到SearchResponse
对象,它包含了搜索结果以及高亮信息等。
六、解析处理高亮搜索的响应结果
- 获取搜索结果
- 从
SearchResponse
中获取搜索到的文档。
- 从
import org.elasticsearch.search.SearchHit;SearchHit[] searchHits = searchResponse.getHits().getHits();
for (SearchHit hit : searchHits) {String sourceAsString = hit.getSourceAsString();// 这里可以对原始文档内容进行处理
}
- 这里我们通过
searchResponse.getHits().getHits()
获取到搜索命中的文档数组,然后可以遍历这些文档。
- 获取高亮结果
- 对于每个搜索命中的文档,我们可以获取其高亮部分。
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
if (highlightFields!= null) {HighlightField highlightField = highlightFields.get("content");if (highlightField!= null) {Text[] fragments = highlightField.getFragments();if (fragments!= null) {for (Text fragment : fragments) {String highlightedFragment = fragment.string();// 这里可以将高亮片段替换到原始文档中的相应位置}}}
}
- 首先我们从
hit
对象中获取HighlightFields
的映射,然后找到我们之前设置高亮的字段(这里是content
)对应的HighlightField
对象。如果存在高亮字段,我们获取其片段(fragments
),这些片段就是包含高亮标记的文本部分。
七、在WEB客户端中呈现高亮搜索结果
- 选择Web框架(以Spring Boot为例)
- 简介
- Spring Boot是一个流行的Java Web开发框架,它简化了Web应用的开发过程。我们可以使用Spring Boot来构建一个Web应用,用于展示Elasticsearch的高亮搜索结果。
- Maven依赖
- 简介
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.5</version>
</dependency>
- 将解析结果传递给视图
- 在Spring Boot的Controller中,我们可以将解析后的高亮搜索结果传递给视图。
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;@Controller
public class SearchController {@GetMapping("/search")public String search(Model model) {// 假设这里已经执行了Elasticsearch搜索并解析了结果List<SearchResult> searchResults = new ArrayList<>();model.addAttribute("searchResults", searchResults);return "search-results";}
}
- 这里我们创建了一个
SearchController
,在search
方法中,我们将搜索结果(假设是SearchResult
类型的列表)添加到Model
对象中,然后返回视图名称(search-results
)。
- 在视图中呈现高亮结果
- 在视图文件(如Thymeleaf模板)中,我们可以这样呈现高亮结果。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>Search Results</title>
</head>
<body><ul th:each="result : ${searchResults}"><li th:text="${result.highlightedTitle}"></li><p th:text="${result.highlightedContent}"></p></ul>
</body>
</html>
- 这里我们使用Thymeleaf的语法,通过
th:each
循环遍历搜索结果列表,然后使用th:text
将高亮的标题和内容显示出来。
八、参考资料文献
- Elasticsearch官方文档
- Spring Boot官方文档
- 相关技术博客和论坛,如Stack Overflow等
相关文章:

【Elasticsearch】高亮搜索:从原理到Web呈现
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…...
samout llm解码 幻觉更低更稳定
这段代码定义了一个简单的对话生成系统,包括模型加载、词汇表加载、以及基于给定提示生成文本的功能。下面是对代码的解析: load_model_and_voc(device"cpu"): 该函数用于加载预训练的模型和词汇表(vocabulary)。它首先…...
单片机:实现多任务处理(附带源码)
单片机实现多任务处理 多任务处理是现代操作系统的重要特性,通常通过多线程、多进程的方式来并行执行多个任务。在嵌入式系统中,由于资源有限,通常通过时间片轮转或中断机制来模拟多任务处理。本项目将展示如何在8051单片机上实现简单的多任…...

负载均衡oj项目:介绍
目录 项目介绍 项目演示 项目介绍 负载均衡oj是一个基于bs模式的项目。 用户使用浏览器向oj模块提交代码,oj模块会在所有在线的后端主机中选择一个负载情况最低的主机,将用户的代码提交给该主机,该主机进行编译运行,将结果返回…...

剑指Offer 03比特位计数
只是记录 题目链接 题目链接 自己想出来的 第一种解法 思路简述 遍历[0,n]之间的数字,对于每一个数字按照二进制的方式展开,判断最低位置是否为1,若为1则1,反之不加,直到该数字等于0就停止。 public static int[] …...

多音轨视频使用FFmpeg删除不要音轨方法
近期给孩子找宫崎骏动画,但是有很多是多音轨视频但是默认的都是日语,电视上看没办法所以只能下载后删除音轨文件只保留中文。 方法分两步,先安装FFmpeg在转文件即可。 第一步FFmpeg安装 FFmpeg是一个开源项目,包含了处理视频的…...
elasticsearch 使用enrich processor填充数据
文章目录 使用 POST 请求手动插入用户数据1. 创建 Enrich Policy步骤 1.1: 创建 Enrich Policy步骤 1.2: 执行 Enrich Policy 2. 创建 Ingest Pipeline步骤 2.1: 创建 Ingest Pipeline步骤 2.2: 配置 Enrich Processor 参数 3. 使用 Ingest Pipeline步骤 3.1: 使用 Pipeline 进…...
VMProtect:软件保护与安全的全面解决方案
在当今数字化时代,软件的安全性和保密性愈发重要。VMProtect 作为一款备受瞩目的软件保护工具,因其强大的功能和广泛的应用而成为开发者保护软件的首选方案。 VMProtect 是一款新一代的软件保护实用程序,支持多个编译器平台,包括…...

Web 毕设篇-适合小白、初级入门练手的 Spring Boot Web 毕业设计项目:教室信息管理系统(前后端源码 + 数据库 sql 脚本)
🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 1.0 项目介绍 开发工具:IDEA、VScode 服务器:Tomcat, JDK 17 项目构建:maven 数据库:mysql 8.0 系统用户前台和管理…...
第十二篇:linux下socket本地套接字通讯
使用套接字除了可以实现网络间不同主机间的通信外,还可以实现同一主机的不同进程间的通信,且建立的通信是双向的通信。socket进程通信与网络通信使用的是统一套接口,只是地址结构与某些参数不同。 用途 进程间通信:本地套…...
Spring Boot 2.1.7 数据源自动加载过程详解
在 Spring Boot 中,数据源的自动配置是框架中一个关键功能,本文将以 Spring Boot 2.1.7 版本为例,详细讲解在单数据源情况下数据源是如何自动加载的。我们通过源码分析,追踪整个加载流程。 1. 自动配置类的发现 Spring Boot 使用…...
【Vue.js 3.0】provide 、inject 函数详解
在 Vue 3 中,provide 和 inject 是用于跨组件层次结构进行依赖注入的一对 API。这些 API 主要用于祖先组件和后代组件之间的数据传递,尤其是当这些组件之间没有直接的父子关系时。 1. 示例 1.1 provide provide 函数用于在祖先组件中定义一个值&#…...

JVM(Java虚拟机)的虚拟机栈
JVM(Java虚拟机)的虚拟机栈是Java程序运行时的重要组件,以下是对其的详细解析: 一、概念与功能 概念:虚拟机栈也称为Java栈,是JVM为每个线程分配的一个私有的内存区域。每个线程在创建时都会创建一个虚拟…...

Elasticsearch02-安装7.x
零、文章目录 Elasticsearch02-安装7.x 1、Windows安装Elasticsearch (1)JDK安装 Elasticsearch是基于java开发的,所以需要安装JDK。我们安装的Elasticsearch版本是7.15,对应JDK至少1.8版本以上。也可以不安装jdk,…...

iPhone恢复技巧:如何从 iPhone 恢复丢失的照片
在计算机时代,我们依靠手机来捕捉和存储珍贵的回忆。但是,如果您不小心删除或丢失了手机上的照片怎么办?这真的很令人沮丧和烦恼,不是吗?好吧,如果您在 iPhone 上丢失了照片,您不必担心…...
vba批量化调整word的图和图表标题
vba代码 将图片进行居中操作 Sub ChangePictureFormate()Dim oPara As ParagraphDim oRange As RangeDim i As LongDim beforeIsPicture As BooleanbeforesIsPicture False 确保文档中至少有图片If ActiveDocument.InlineShapes.Count 0 ThenMsgBox "没有找到图片。&qu…...

【Flutter_Web】Flutter编译Web第二篇(webview篇):flutter_inappwebview如何改造方法,变成web之后数据如何交互
前言 欢迎来到第二篇文章,这也是第二个难题,就是原有的移动端本身一些页面H5的形式去呈现(webview),例如某些需要动态更换内容的页面,某些活动页面、支付页面,不仅仅做页面呈现,还包…...

【C语言的奥秘11】指针知识点总结(续)
目录 一、指针的运算 1、指针与整数相加减 2、指针-指针(地址-地址) 3、指针的关系运算 六、指针和数组 七、二级指针 八、指针数组 一、指针的运算 1、指针与整数相加减 看一下下面的代码: #include<stdio.h> int my_strlen(c…...
excel 列名是数据表 的字段名 ,单元格的值 是数据表对应字段的值,生成sql插入语句
在 Excel 中,按 Alt F11 打开 VBA 编辑器。在菜单栏选择 插入 -> 模块,在新模块中粘贴以下代码。 VBA 代码 Sub GenerateSQLInsertStatementsToFile()Dim ws As WorksheetDim lastRow As Long, lastCol As Long, i As Long, j As LongDim sql As S…...

AI Agent与MEME:技术与文化融合驱动Web3创新
AI Agent如何引领Web3新时代? 随着Web3与区块链技术的迅速发展,AI Agent作为人工智能与区块链的交汇点,正在逐步成为推动去中心化生态的重要力量。同时,MEME文化凭借其强大的社区驱动力和文化渗透力,在链上生态中扮演着…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...

算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...

Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...