【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文化凭借其强大的社区驱动力和文化渗透力,在链上生态中扮演着…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...

学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...