详解Elastic Search高速搜索背后的秘密:倒排索引


在这里插入图片描述

🎬 鸽芷咕:个人主页

 🔥 个人专栏: 《C++干货基地》《粉丝福利》

⛺️生活的理想,就是为了理想的生活!

引入

全文搜索属于最常见的需求,开源的 Elasticsearch (以下简称 Elastic)是目前全文搜索引擎的首选,相信大家多多少少的都听说过它。它可以快速地储存、搜索和分析海量数据。就连维基百科、Stack Overflow、Github 都采用它选择作为自己的搜索引擎今天就让我们来了解了解 Elasticsearch 为什么这么快它的架构介绍及原理解析。

文章目录

  • 引入
  • 一 、Elastic Search的简介
  • 二、什么是倒排索引
    • 2.1 倒排索引讲解
  • 三、倒排索引的工作原理
    • 3.1 分词与索引构建
    • 3.2 索引存储与优化
    • 3.3 查询处理
  • 四、构建倒排索引的源码解析
  • 五、实战教学
    • 5.1 创建索引和映射
    • 5.2 添加文档
    • 5.3 搜索文档
  • 总结

一 、Elastic Search的简介

Elastic Search(简称ES)是一个基于Apache Lucene构建的开源、分布式、RESTful搜索和分析引擎。它允许你快速地存储、搜索和分析大量数据。ES通常用于日志分析、全文搜索等复杂的数据分析场景。

二、什么是倒排索引

倒排索引是一种用于快速检索的数据结构,常用于搜索引擎和数据库中。与传统的正排索引不同,倒排索引是根据关键词来建立索引,而不是根据文档ID。

2.1 倒排索引讲解

下面我们用一个简单的例子描述一下倒排索引的作用过程:

假如现在有三份数据文档,内容分别是:

代码语言:javascript

Doc 1:Java is the best programming languageDoc 2:PHP is the best programming languageDoc 3:Javascript is the best programming language

为了创建索引,ES引擎通过分词器将每个文档的内容拆成单独的词(称之为词条,或term),再将这些词条创建成不含重复词条的排序列表,然后列出每个词条出现在哪个文档,结果如下:

在这里插入图片描述

这种结构由文档中所有不重复的词的列表构成,对于其中每个词都有至少一个文档与与之关联。这种由属性值来确定记录的位置的结构就是倒排索引,带有倒排索引的文件被称为倒排文件。

将上表转为更直观的图片来展示倒排索引:

在这里插入图片描述

三、倒排索引的工作原理

3.1 分词与索引构建

首先,搜索引擎会对文档内容进行分词处理,将文本拆分成独立的单词或词组。然后,为每个单词或词组创建一个倒排列表,该列表记录了包含该单词或词组的所有文档的ID和该单词在文档中的位置信息(如偏移量、词频等)。

3.2 索引存储与优化

接下来,搜索引擎会将这些倒排列表存储在磁盘上,并进行一系列的优化操作,如压缩、合并等,以减少存储空间和提高查询效率。这些优化操作使得倒排索引在保持高效查询性能的同时,也具有良好的可扩展性和稳定性。

3.3 查询处理

当用户发起搜索请求时,搜索引擎会对查询语句进行分词处理,并生成一个查询词列表。然后,根据这个查询词列表在倒排索引中查找对应的倒排列表,并将这些倒排列表进行交集运算,以找到同时包含所有查询词的文档。最后,根据一定的排序算法对结果进行排序,并返回给用户。

四、构建倒排索引的源码解析

public class IndexWriter {// ... 其他属性和方法public void addDocument(Document doc) throws IOException {// Document 是一个容器,存储了待索引的字段和值// ... 初始化和准备阶段的代码// 遍历文档的每个字段for (IndexableField field : doc) {// 获取字段的名称和值String name = field.name();String value = field.stringValue();// 使用分析器对文本进行分词Analyzer analyzer = getAnalyzer();TokenStream tokenStream = analyzer.tokenStream(name, value);tokenStream.reset();// 遍历分词结果,构建倒排索引while (tokenStream.incrementToken()) {CharTermAttribute termAtt = tokenStream.getAttribute(CharTermAttribute.class);String termText = termAtt.toString();// 此处的 termText 即为分词后的词项// 将词项加入到倒排索引中,此处为简化示例,具体实现会涉及到词项的存储、文档的标识、词项在文档中的位置等信息addTermToInvertedIndex(name, termText, docId);}tokenStream.end();tokenStream.close();}// ... 后续的索引更新和维护代码}private void addTermToInvertedIndex(String fieldName, String termText, int docId) {// 此方法用于将词项加入到倒排索引中// 在实际的 Lucene 源码中,这里会涉及到更复杂的数据结构和算法来存储和管理倒排索引// ... 具体的实现代码}// ... 其他属性和方法
}

五、实战教学

5.1 创建索引和映射

首先,我们需要创建一个索引,并为该索引定义一个映射(mapping),以确定文档的结构。

import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;public class CreateIndexExample {public static void createBlogIndex(RestHighLevelClient client) {CreateIndexRequest request = new CreateIndexRequest("blog");request.source("{\"properties\": {\"title\": {\"type\": \"text\"},\"content\": {\"type\": \"text\"}}");try {CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);System.out.println(createIndexResponse.isAcknowledged());} catch (IOException e) {e.printStackTrace();}}
}

5.2 添加文档

接下来,我们可以向我们的索引中添加一些文档。

import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;public class AddDocumentExample {public static void addBlogPost(RestHighLevelClient client, String id, String title, String content) {IndexRequest request = new IndexRequest("blog").id(id);request.source("{\"title\": \"" + title + "\", \"content\": \"" + content + "\"}");try {IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);System.out.println(indexResponse.getId());} catch (IOException e) {e.printStackTrace();}}
}

5.3 搜索文档

import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;public class SearchDocumentExample {public static void searchPost(RestHighLevelClient client, String query) {SearchRequest searchRequest = new SearchRequest("blog");SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.matchQuery("title", query));searchRequest.source(searchSourceBuilder);try {SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);for (SearchHit hit : searchResponse.getHits().getHits()) {System.out.println(hit.getSourceAsString());}} catch (IOException e) {e.printStackTrace();}}
}

总结

过这个简单的实战示例,我们可以看到Elasticsearch的倒排索引如何使得文本搜索变得高效。倒排索引的核心思想是将单词或词组映射到包含它们的文档上,这样我们就可以直接查询倒排索引来找到包含特定单词的文档,而不需要逐个检查每个文档的内容。这使得Elasticsearch成为一个非常强大的搜索引擎,适用于各种需要高效文本搜索的场景。

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

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

相关文章

Python应用开发——30天学习Streamlit Python包进行APP的构建(10)

st.map 显示一张叠加了散点图的地图。 它是 st.pydeck_chart 的包装器,用于在地图上快速创建散点图表,并具有自动居中和自动缩放功能。 使用该命令时,Mapbox 会提供地图瓦片来渲染地图内容。请注意,Mapbox 是第三方产品&#x…

海云安参编《数字安全蓝皮书 》正式发布并入选《2024中国数字安全新质百强》荣膺“先行者”

近日,国内数字化产业第三方调研与咨询机构数世咨询正式发布了《2024中国数字安全新质百强》(以下简称百强报告)。海云安凭借在开发安全领域的技术创新力及市场影响力入选百强报告“新质百强先行者” 本次报告,数世咨询经过对国内8…

AJAX 实例:深入解析与实战应用

AJAX 实例:深入解析与实战应用 引言 AJAX(Asynchronous JavaScript and XML)是一种无需重新加载整个网页的情况下,能够更新部分网页的技术。自2005年提出以来,AJAX已成为现代Web开发的重要组成部分,极大地提升了用户体验和网页性能。本文将通过一系列实例,深入解析AJA…

用Verilog实现4位计数器(时序逻辑)

用Verilog实现4位计数器。(时序逻辑) 实验目的: 通过用Verilog实现4位计数器,进一步熟悉Verilog的语法和时序逻辑电路。 实验描述: 输入: Clock:如果计数器enable信号为1,那么在…

多功能气象传感器的工作原理

TH-WQX9多功能气象传感器是一种集成了多种传感器技术的气象观测装置,旨在同时测量和监测大气中的多个气象要素,以提供全面、准确的气象信息。以下是关于多功能气象传感器的详细介绍: 技术原理 多功能气象传感器采用多种传感器技术相结合&…

深入理解Git:rebase与merge

在Git的版本控制中,rebase和merge是两个至关重要的操作,它们用于整合不同分支的修改。然而,很多开发者在使用时容易混淆,今天我们就来详细解析一下两者的区别、优缺点,并通过实战代码来演示它们的用法。 一、rebase与…

Linux(Ubuntu)下源码开发整个流程完成版本(下载->编译->模拟器运行)

写这篇文章没别的意思, 年纪大了记性不好, 这次工作中下载,编译遇到了一些之前没遇到的问题,所以就所幸记录一下, 以便日后能快速查阅 好了, 正题开始 首先我们下载AOSP源代码开始 AOSP源代码下载 首先找到官网https://source.android.google.cn/ 进入后最上面点击获取源代…

day01-项目介绍及初始化-登录页

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 day01-项目介绍及初始化-登录页一、人力资源项目介绍1.1项目架构和解决方案主要模块解决的问题 二、拉取项目基础代码1.引入库2.升级core-js版本到3.25.5按照完整依…

LSTM时间序列基础学习

时间序列 时间序列可以是一维,二维,三维甚至更高维度的数据,在深度学习的世界中常见的是三维时间序列,这三个维度分别是(batch_size,time_step,input_dimensions)。 其中time_step是时间步,它…

jenkins中执行docker命令

1. 修改docker.sock文件的所属组 命令如下: sudo chown root:root docker.sock 2. 对这个文件赋予权限,供其他用户使用,给定权限命令如下: sudo chmod orw docker.sock 3. docker容器映射 这里需要两个文件: 一个…

js-iframe-同源策略-addEventListener-postMessage-父子框架

文章目录 1.同源策略2.不同源解决办法-postMessage不受跨域的影响2.1.addEventListener函数监听消息2.2.父传子-不同源2.3.子传父-不同源 3.通过父页面操作子页面-同源3.1.值3.2.函数 4.通过子页面操作父页面-同源4.1.值4.2.函数 1.同源策略 在HTML页面中,我们有时…

等保主机测评防骗指南(资产调研)

你是否测评时常被运维给忽悠?是否觉得以下的对话耳熟? 你:您好,请问你们的主机资产有哪些,包括服务器、数据库、中间件、应用系统等。 甲:我们资产就这两台服务器,数据库什么的都这上面&#…

中断的“挂起状态”

中断的“挂起状态”(Pending State)是指中断信号已经被系统识别,但尚未被处理器处理的状态。在微控制器或计算机系统中,中断通常是程序外部事件(如硬件设备的信号)触发的信号,用于通知处理器需要…

C++关键字总结

1.数据类型 bool:布尔类型,属于基本类型的整数类型,取值为真和假 true:具有布尔类型的字面量,表示真 false:具有布尔类型的字面量,表示假 char:表示字符型,定义了字节的大小,char表示单字节字符 wchar_t:表…

蛇形矩阵(xmuoj)

描述 输入两个整数n和m,输出一个n行m列的矩阵,将数字11到nm按照回字蛇形填充至矩阵中。 具体矩阵形式可参考样例。 输入 输入共一行,包含两个整数n和m。 输出 输出满足要求的矩阵。 矩阵占n行,每行包含m个空格隔开的整数。…

TMGM:ASIC撤销禁令,TMGM强化合规、重启差价合约服务

TMGM作为差价合约(CFDs)与保证金外汇交易领域的领航者,安全、合规、高效被奉为我集团的终身使命。澳大利亚证券和投资委员会(ASIC)已正式撤销了早前针对TMGM差价合约业务实施的临时止损令。这一误会的解除,…

降低IT运营成本,提升客户体验 |LinkSLA亮相第十届CDIE

6月25-26日,中国数字化创新博览会(CDIE 2024)在上海张江科学会堂举行。本届展览主题为“AI创新,引领商业增长新格局”,旨在交流企业在数字化时代,如何以科技为驱动,在转型中如何把握机遇&#x…

Springboot + Mybatis-Plus代码生成指南

使用 Spring Boot 和 MyBatis-Plus 生成代码&#xff0c;可以大大简化开发流程&#xff0c;可以保持编码的规范性&#xff0c;生成单元测试等。以下是详细步骤&#xff1a; 配置pom.xml <dependency><groupId>com.baomidou</groupId><artifactId>myb…

【D3.js in Action 3 精译】推荐序

作为一名自由职业的数据可视化教育从业人员、咨询顾问和设计师&#xff0c;我从 2000 年代末开始就深深沉浸在数据可视化的各个角落&#xff0c;有幸坐到前排亲眼目睹了巨大的产业变革。数据可视化的技术格局一直在推陈出新。从行业工具的发展演变&#xff0c;到触达受众的可视…

如何利用静力水准仪进行地形沉降测量

地形沉降测量在建筑工程和地质研究中起着至关重要的作用。准确的地形沉降测量可以帮助工程师预测和预防潜在的地基问题&#xff0c;从而保障建筑物的安全和稳定。本文将详细介绍如何利用静力水准仪进行地形沉降测量&#xff0c;并探讨其在实际应用中的优势。 静力水准仪的基本原…