【Elasticsearch】全文搜索与相关性排序

🧑 博主简介:CSDN博客专家历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c=1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编程高并发设计Springboot和微服务,熟悉LinuxESXI虚拟化以及云原生Docker和K8s,热衷于探索科技的边界,并将理论知识转化为实际应用。保持对新技术的好奇心,乐于分享所学,希望通过我的实践经历和见解,启发他人的创新思维。在这里,我希望能与志同道合的朋友交流探讨,共同进步,一起在技术的世界里不断学习成长。
技术合作请加本人wx(注明来自csdn):foreast_sea

在这里插入图片描述


在这里插入图片描述

【Elasticsearch】全文搜索与相关性排序

引言

在当今数字化信息爆炸的时代,高效准确的搜索功能成为了众多应用不可或缺的一部分。无论是电商平台上查找心仪的商品,还是在海量文档库中迅速定位所需资料,强大的搜索能力都能极大提升用户体验和工作效率。而 Elasticsearch 作为一款流行的分布式搜索引擎,以其卓越的全文搜索和灵活的相关性排序功能脱颖而出,成为了众多开发者和企业的首选。

全文搜索,简单来说,就是在文本数据中根据用户输入的关键词找到与之相关的文档。但这一过程背后却蕴含着复杂而精妙的技术原理。从用户输入关键词的那一刻起,Elasticsearch 需要经过多个步骤来理解用户意图,并从海量数据中筛选出最相关的结果。这其中涉及到文本分析,即将输入的文本转化为计算机能够理解和处理的形式;倒排索引的构建与使用,它是实现快速搜索的关键数据结构。

相关性排序则是另一个关键环节。搜索结果的排序直接影响用户获取信息的效率和满意度。Elasticsearch 提供了丰富的排序策略,可以根据关键词的匹配程度、文档的新鲜度、字段的权重等多种因素进行综合排序。通过合理运用这些排序机制,我们能够让搜索结果更加符合用户的期望,将最有价值的信息呈现给用户。

在接下来的文章中,我们将深入探索 Elasticsearch 的全文搜索原理和相关性排序机制。通过详细的理论阐述、实际案例分析以及代码示例,帮助读者全面掌握这两项核心技术,为开发出高效智能的搜索应用奠定坚实的基础。

一、Elasticsearch 简介

Elasticsearch 是一个基于 Lucene 的分布式、RESTful 风格的开源搜索引擎。它旨在提供分布式环境下的全文搜索、结构化搜索以及分析功能。Elasticsearch 具备高可用性、可扩展性和高性能等特点,能够处理 PB 级别的数据。

1.1 分布式架构

Elasticsearch 采用分布式架构,允许将数据分散存储在多个节点上。一个 Elasticsearch 集群可以包含多个节点,每个节点可以存储数据的一部分。这种分布式存储方式不仅提高了数据的可靠性和可用性,还能够通过并行处理提高搜索性能。

1.2 RESTful API

Elasticsearch 通过 RESTful API 与外部系统进行交互。开发者可以使用 HTTP 请求来创建索引、插入文档、执行搜索查询等操作。这种简单易用的 API 使得 Elasticsearch 能够方便地集成到各种应用程序中。

二、Elasticsearch 的 Maven 依赖

在使用 Elasticsearch 进行开发时,我们需要在项目中引入相应的 Maven 依赖。以下是一些常用的依赖:

2.1 Elasticsearch 客户端依赖

<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.17.4</version>
</dependency>

这个依赖提供了高级 REST 客户端,用于与 Elasticsearch 集群进行交互。它封装了底层的 HTTP 操作,提供了更方便的 API 来执行各种操作,如索引管理、文档操作和搜索查询等。

2.2 Elasticsearch 核心依赖

<dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.17.4</version>
</dependency>

Elasticsearch 核心依赖包含了 Elasticsearch 的核心功能和类库。它是整个 Elasticsearch 运行的基础,提供了数据存储、索引构建、搜索算法等核心功能。

2.3 其他依赖

根据项目的具体需求,可能还需要引入其他依赖,如 JSON 处理库、日志库等。例如,Jackson 库用于处理 JSON 数据,在 Elasticsearch 中用于文档的序列化和反序列化:

<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.13.4</version>
</dependency>

日志库如 Log4j 或 SLF4J 可以帮助我们记录 Elasticsearch 客户端的运行日志,方便调试和监控:

<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.32</version>
</dependency>
<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.32</version>
</dependency>
<dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version>
</dependency>

三、全文搜索原理

3.1 文本分析过程

文本分析是 Elasticsearch 全文搜索的第一步,它的目的是将输入的文本转化为适合搜索的形式。文本分析主要包括以下几个阶段:

3.1.1 字符过滤(Character Filter)

字符过滤阶段会对输入的原始文本进行预处理,例如去除 HTML 标签、转换特殊字符等。Elasticsearch 提供了多种字符过滤器,如 html_strip 字符过滤器可以去除文本中的 HTML 标签。

3.1.2 分词(Tokenizer)

分词是将文本分割成一个个独立的词(token)的过程。不同的语言和应用场景需要不同的分词器。例如,对于英文文本,常用的分词器有 standard 分词器,它会根据空格和标点符号进行分词;对于中文文本,常用的分词器有 ik 分词器,它能够对中文进行智能分词。

3.1.3 词元转换(Token Filter)

词元转换阶段会对分词后的词元进行进一步处理,例如将词元转换为小写、去除停用词(如“的”“是”“在”等无实际意义的词)、进行词干提取(将单词转换为其基本形式)等。

3.2 倒排索引的构建

倒排索引是 Elasticsearch 实现快速搜索的核心数据结构。它与传统的正向索引相反,正向索引是从文档到词的映射,而倒排索引是从词到文档的映射。

假设我们有以下三个文档:

  • 文档 1:“Elasticsearch is a powerful search engine”
  • 文档 2:“Lucene is the foundation of Elasticsearch”
  • 文档 3:“Search engines are essential for information retrieval”

经过文本分析后,我们得到了一系列的词元。倒排索引会将每个词元映射到包含该词元的文档列表。例如,“Elasticsearch”这个词元会映射到文档 1 和文档 2;“search”这个词元会映射到文档 1 和文档 3。

在 Elasticsearch 中,倒排索引以段(Segment)的形式存储在磁盘上。每个段都是一个独立的倒排索引,随着新文档的不断插入,会生成多个段。为了提高搜索效率,Elasticsearch 会定期将多个段合并成一个更大的段。

3.3 倒排索引的使用

当用户发起一个搜索请求时,Elasticsearch 首先会对用户输入的关键词进行文本分析,得到相应的词元。然后,根据这些词元在倒排索引中查找包含这些词元的文档列表。

例如,用户搜索“Elasticsearch search”,Elasticsearch 会对这两个关键词进行文本分析,得到“elasticsearch”和“search”这两个词元。接着,在倒排索引中查找这两个词元对应的文档列表,最后将两个文档列表进行合并和排序,得到最终的搜索结果。

四、相关性排序

4.1 根据关键词匹配程度排序

关键词的匹配程度是影响相关性排序的重要因素之一。Elasticsearch 使用 BM25 算法来计算文档与关键词的匹配程度。BM25 算法考虑了多个因素,如词频(关键词在文档中出现的次数)、文档长度、逆文档频率(关键词在整个索引中出现的文档数的倒数)等。

以下是一个简单的搜索请求示例,使用 match 查询来搜索“Elasticsearch”,并按照默认的相关性排序返回结果:

SearchRequest searchRequest = new SearchRequest("your_index");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("content", "Elasticsearch"));
searchRequest.source(searchSourceBuilder);RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

4.2 根据文档新鲜度排序

在一些应用场景中,我们希望最新的文档排在前面。Elasticsearch 可以通过文档的时间戳字段来实现按新鲜度排序。

假设我们的文档中有一个 timestamp 字段记录文档的创建时间,以下是一个按新鲜度排序的搜索请求示例:

SearchRequest searchRequest = new SearchRequest("your_index");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchSourceBuilder.sort(new FieldSortBuilder("timestamp").order(SortOrder.DESC));
searchRequest.source(searchSourceBuilder);RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

4.3 根据字段权重排序

不同的字段在搜索结果中的重要性可能不同。我们可以通过设置字段的权重来影响相关性排序。例如,在一个商品搜索应用中,商品标题字段可能比商品描述字段更重要,我们可以给标题字段设置更高的权重。

以下是一个设置字段权重的搜索请求示例:

SearchRequest searchRequest = new SearchRequest("your_index");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.multiMatchQuery("keyword", "title^3", "description"));
searchRequest.source(searchSourceBuilder);RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

在这个示例中,title^3 表示给 title 字段设置了 3 倍的权重。

4.4 综合排序

在实际应用中,我们通常需要综合考虑多个因素进行排序。例如,我们希望先按关键词匹配程度排序,然后在匹配程度相同的情况下按文档新鲜度排序。

以下是一个综合排序的搜索请求示例:

SearchRequest searchRequest = new SearchRequest("your_index");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("content", "keyword"));
searchSourceBuilder.sort(new FieldSortBuilder("timestamp").order(SortOrder.DESC));
searchRequest.source(searchSourceBuilder);RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

五、总结

通过深入了解 Elasticsearch 的全文搜索原理和相关性排序机制,我们能够充分发挥其强大的搜索功能,为用户提供更加高效准确的搜索体验。在实际应用中,我们需要根据具体的业务需求,合理运用文本分析、倒排索引以及各种排序策略,不断优化搜索性能和结果质量。

Elasticsearch 作为一款功能强大的搜索引擎,在不断发展和完善。开发者需要持续关注其官方文档和最新版本,掌握新的特性和功能,以应对日益复杂的搜索需求。希望本文能够帮助读者更好地理解和应用 Elasticsearch 的全文搜索与相关性排序技术,为开发出优秀的搜索应用提供有益的参考。

参考资料文献

  1. Elasticsearch 官方文档
  2. 《Elasticsearch 实战》,Riverside Publishing
  3. 《Lucene 实战》,Manning Publications Co.

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

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

相关文章

【算法】枚举

枚举 普通枚举1.铺地毯2.回文日期3.扫雷 二进制枚举1.子集2.费解的开关3.Even Parity 顾名思义&#xff0c;就是把所有情况全都罗列出来&#xff0c;然后找出符合题目要求的那一个。因此&#xff0c;枚举是一种纯暴力的算法。一般情况下&#xff0c;枚举策略都是会超时的。此时…

51单片机——DS18B20温度传感器

由于DS18B20数字温度传感器是单总线接口&#xff0c;所以需要使用51单片机的一个IO口模拟单总线时序与DS18B20通信&#xff0c;将检测的环境温度读取出来 1、DS18B20模块电路 传感器接口的单总线管脚接至单片机P3.7IO口上 2、DS18B20介绍 2.1 DS18B20外观实物图 管脚1为GN…

云手机技术怎么实现的?

前言 随着亚矩阵云手机在跨境电商、海外社媒矩阵搭建、出海运营、海外广告投放、国内新媒体矩阵运营、品牌应用矩阵运营等领域内的普及和使用&#xff0c;云手机的理念已经被越来越多人所接受和认同。今天我们就一起来浅析一下&#xff0c;到底云手机的技术是怎么实现的&#…

HTML中link的用法

一点寒芒先到&#xff0c;随后&#xff0c;抢出如龙&#xff01; 对于本人而言&#xff0c;这篇笔记内容有些扩展了&#xff0c;有些还未学到的也用上了&#xff0c;但是大概可以使用的明白&#xff0c;坚持下去&#xff0c;相信一定可以建设一个稳固的根基。 该文章为个人成…

闪豆多平台视频批量下载器

1. 视频链接获取与解析 首先&#xff0c;在哔哩哔哩网页中随意点击一个视频&#xff0c;比如你最近迷上了一个UP主的美食制作视频&#xff0c;想要下载下来慢慢学。点击视频后&#xff0c;复制视频页面的链接。复制完成后&#xff0c;不要急着关闭浏览器&#xff0c;因为接下来…

Vulnhub DC-8靶机攻击实战(一)

导语   Vulnhub DC-8靶机教程来了,好久没有更新打靶的教程了,这次我们在来更新一期关于Vulnhub DC-8的打靶训练,如下所示。 安装并且启动靶机 安装并且启动靶机,如下所示。 开始信息采集 进入到Kali中,通过如下的命令来查找到靶机的IP地址。 arp-scan -l根据上面的结…

JWT在线解密/解码 - 加菲工具

JWT在线解密/解码 首先进入加菲工具 选择 “JWT 在线解密/解码” https://www.orcc.online 或者直接进入JWT 在线解密/解码 https://www.orcc.online/tools/jwt 进入功能页面 使用 输入对应的jwt内容&#xff0c;点击解码按钮即可

换了城市ip属地会变吗?为什么换了城市IP属地不变

当我们跨越城市的界限&#xff0c;从一个地方迁移到另一个地方时&#xff0c;许多日常使用的网络服务和应用程序都会感知到这种变化&#xff0c;其中一个显著的现象就是IP属地的变化。IP属地&#xff0c;即IP地址所在的地理位置信息&#xff0c;它通常与互联网服务提供商&#…

如何在谷歌浏览器中设置自定义安全警告

随着网络环境的日益复杂&#xff0c;浏览器的安全问题也愈发引人关注。谷歌浏览器作为一款广泛使用的浏览器&#xff0c;其自定义安全警告功能为用户提供了更加个性化和安全的浏览体验。本文将详细介绍如何在谷歌浏览器中设置自定义安全警告&#xff0c;帮助用户更好地保护自己…

深度学习中的卷积和反卷积(四)——卷积和反卷积的梯度

本系列已完结&#xff0c;全部文章地址为&#xff1a; 深度学习中的卷积和反卷积&#xff08;一&#xff09;——卷积的介绍 深度学习中的卷积和反卷积&#xff08;二&#xff09;——反卷积的介绍 深度学习中的卷积和反卷积&#xff08;三&#xff09;——卷积和反卷积的计算 …

Mongodb相关内容

Mongodb相关内容 1、Windows平台安装2、Linux平台安装3、基本常用命令文档更新删除文档分页查询索引 pymongo操作 客户端下载&#xff1a;https://download.csdn.net/download/guoqingru0311/90273435 1、Windows平台安装 方式一&#xff1a; 方式2&#xff1a; 方式3&#…

RabbitMQ前置概念

文章目录 1.AMQP协议是什么&#xff1f;2.rabbitmq端口介绍3.消息队列的作用和使用场景4.rabbitmq工作原理5.整体架构核心概念6.使用7.消费者消息推送限制&#xff08;work模型&#xff09;8.fanout交换机9.Direct交换机10.Topic交换机&#xff08;推荐&#xff09;11.声明队列…

[Mac + Icarus Verilog + gtkwave] Mac运行Verilog及查看波形图

目录 1. MAC安装环境 1. 1 Icarus Verilog 编译 1. 2 gtkwave 查看波形 2. 安装遇到的问题 2. 1 macOS cannot verify that this app is free from malware 2. 2 gtkwave-bin is not compatible with macOS 14 or later 3. 运行示例 3. 1 源代码 3. 2 编译Verilog 3. 3 生成.v…

kalilinux - 目录扫描之dirsearch

情景导入 先简单介绍一下dirsearch有啥用。 假如你现在访问一个网站&#xff0c;例如https://www.example.com/ 它是一个电商平台或者其他功能性质的平台。 站在开发者的角度上思考&#xff0c;我们只指导https://www.example.com/ 但不知道它下面有什么文件&#xff0c;文…

如何制作符合自己设备的FLM下载算法

如何制作符合自己设备的FLM下载算法 --------以I.MXRT1062 QSPI FLAH为例&#xff08;串行qspi nor flash&#xff09; 本文介绍一种基于i.mxrt1062的外挂flah的qspi nor flash下载算法FLM的一种方法&#xff0c;Flash 编程算法是一种用于擦除或下载应用程序到 Flash 设备的软…

LLMs之RAG:《EdgeRAG: Online-Indexed RAG for Edge Devices》翻译与解读

LLMs之RAG&#xff1a;《EdgeRAG: Online-Indexed RAG for Edge Devices》翻译与解读 导读&#xff1a;这篇论文针对在资源受限的边缘设备上部署检索增强生成 (RAG) 系统的挑战&#xff0c;提出了一种名为 EdgeRAG 的高效方法。EdgeRAG 通过巧妙地结合预计算、在线生成和缓存策…

基于Java的百度AOI数据解析与转换的实现方法

目录 前言 一、AOI数据结构简介 1、官网的实例接口 2、响应参数介绍 二、Java对AOI数据的解析 1、数据解析流程图 2、数据解析实现 3、AOI数据解析成果 三、总结 前言 在当今信息化社会&#xff0c;地理信息数据在城市规划、交通管理、商业选址等领域扮演着越来越重要的…

【C++】构造函数与析构函数

写在前面 构造函数与析构函数都是属于类的默认成员函数&#xff01; 默认成员函数是程序猿不显示声明定义&#xff0c;编译器会中生成。 构造函数和析构函数的知识需要建立在有初步类与对象的基础之上的&#xff0c;关于类与对象不才在前面笔记中有详细的介绍&#xff1a;点我…

2013年IMO几何预选题第4题

在 △ A B C \triangle ABC △ABC 中, A B < A C AB < AC AB<AC. P P P, Q Q Q 是直线 A C AC AC 上的两个不同的点, 满足 ∠ P B A ∠ Q B A ∠ A C B \angle PBA \angle QBA \angle ACB ∠PBA∠QBA∠ACB, 且 A A A 在 P P P 与 C C C 之间. 已知在线段…

UDP报文格式

UDP是传输层的一个重要协议&#xff0c;他的特性有面向数据报、无连接、不可靠传输、全双工。 下面是UDP报文格式&#xff1a; 1&#xff0c;报头 UDP的报头长度位8个字节&#xff0c;包含源端口、目的端口、长度和校验和&#xff0c;其中每个属性均为两个字节。报头格式为二…