ElasticSearch:全文检索及倒排索引原理

在这里插入图片描述

1.从全文检索说起

首先介绍一下结构化与非结构化数据:

  • 结构化数据将数据具有的特征事先以结构化的形式定义好,数据有固定的格式或有限的长度。典型的结构化数据就是传统关系型数据库的表结构,数据特征直接体现在表结构的字段上,所以根据某一特征做数据检索很直接,速度也比较快
  • 非结构化数据没有预先定义好的结构化特征,也没有固定格式和固定长度。典型的非结构化数据包括文章、图片、视频、网页、邮件等,其中像HTML网页这种具有一定格式的文档也称为半结构化数据

对于非结构化的数据检索,被称为全文检索。

假设现在MySQL中有一张User表,含有三个阶段:姓名name、年龄age和爱好favor:

对于User表来说,整体上是结构化的,比如name、age都可以直接建立索引来快速地检索。
而其中的favor字段是一个text类型,存储的是非结构化的文本数据:
篮球、足球、爱运动的我;本人热爱学习,游戏偶尔也玩!!!!

与结构化查询相比,全文检索面临的最大问题就是性能问题。全文检索最一般的应用场景是根据一些关键字查找包含这些关键字的文档,比如互联网搜索引擎要实现的功能就是根据一些关键字查找网页。显然,如果没有对文档做特别处理,查找的办法似乎只能是逐条比对。

假设现在需要找到favor中含有“足球”这个关键字的User,那么只能使用like模糊查询:
select * from user where favor like '%足球%'

like语句是无法建立索引的,查询时会进行全表扫描,并且在每个favor字段中进行遍历匹配,以找到含有“足球”这个关键字的记录,整体复杂度特别高,所以全文检索也是MySQL这类结构关系式数据库无法很好实现的需求。

全文检索一般是查询包含某一或某些关键字记录,所以通过文档整体值建立的索引对提高查询速度是没有任何帮助的。为了解决这个问题,人们创建了一种新索引方法,这种索引方法就是倒排索引。

2.倒排索引的原理

倒排索引是为了解决上述非结构化数据的检索问题而产生的。

首先明确一下,在ES中存储记录的单位是JSON“文档”,而JSON“文档”中的“字段”也就是组成JSON的一个个KV对。

普通索引也被称为正排索引,也就是通过对主键和结构化字段建立索引,通过这些结构化索引找到文档。

倒排索引则是先将文档中包含的关键字全部提取出来,然后再将关键字与文档的对应关系保存起来,最后再对关键字本身做索引排序。用户在检索某一关键字时,可以先对关键字的索引进行查找,再通过关键字与文档的对应关系找到所在文档。

假设上述的User表通过ES存储,其中两个User文档为:

{"_id: 1,"name":"pbr1","age":22,"favor":"篮球、足球、爱运动的我;本人热爱学习,游戏偶尔也玩!!!!"
}{"_id: 2,"name":"pbr2","age":22,"favor":"篮球、足球、爱运动的我"
}

其中favor定义为text类型,假设分词器进行以下分词:

  • 文档1的favor分词:“篮球”、“足球”、“爱运动的我”、“本人热爱学习”、“游戏偶尔也玩”这5个token
  • 文档2的favor分词:“篮球”、“足球”、“爱运动的我”这3个token

那么对分词token建立索引,并建立对原始文档的映射,就得到一个以favor进行分词的倒排索引:
在这里插入图片描述

可以看到,倒排索引实际上就是对全文数据结构化的过程。对于存储在关系型数据库中的数据来说,它们依赖于人的预先分析将数据拆解为不同字段,所以在数据插入时就已经是结构化的;而在全文数据库中,文档在插入时还不是结构化的,需要应用程序根据规则自动提取关键字,并形成关键字与文档之间的结构化对应关系。

比如现在需要查询爱好为“篮球”和“足球”的用户,那么可以直接通过倒排索引拿到对应的文档1和文档2,也就查询到了这两个用户。

3.ES索引构建过程

全文检索中提取关键字是非常重要的一步。这些预先提取出来的关键字,在Elasticsearch及全文检索的相关文献中一般称为词项(Term),文档的词项提取在Elasticsearch中称为文档分析(Analysis),是整个全文检索中较为核心的过程。这个过程必须要区分哪些是词项,哪些不是。对于英文来说,它还必须要知道apple和apples指的同一个东西,而run和running指的是同一动作。对于中文来说就更麻烦了,因为中文词语不以空格分隔,所以面临的第一难题是如何将词语分辨出来。

ES底层使用了Lucene来构建索引,一个基本的过程是先对text类型的字段进行分词,分词使用的分词器以配置mapping时指定的为准,默认使用standard分词器,对于中文分词来说,一般建议使用ik_smart或ik_max_word分词器:

暂时无法在文档外展示此内容

关于Lucene如何存储这些分词解析结果可以学习这篇文章:https://www.shenyanchao.cn/blog/2018/12/04/lucene-index-files/

由于文档存储前的分析和索引过程比较耗资源,所以为了提升性能,文档在添加到ES中时并不会立即被编入索引。

默认情况下,ES会每隔1s统一处理一次新加入的文档,可以通过index.refresh_interval参数修改。

为了提升性能,在ES 7中还添加了index.search.idle.after参数,它的默认值是30s:如果索引在一段时间内没有收到检索数据的请求,那么它至少要等30s后才会刷新索引数据。

所以可以看出ES的写入操作实际上是准实时的,新添加到索引中的文档可能在一段时间内不能被检索到,如果的确需要立即检索到文档可以使用强制刷新到索引的方式,包括使用_refresh接口和在操作文档时使用refresh参数等进行强制刷新缓冲区中的索引到磁盘中。

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

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

相关文章

电商数据获取:网络爬虫还是付费数据接口?

随着电商行业的迅速发展,对电商数据的需求也越来越大。在获取电商数据时,常常面临一个选择:是自己编写网络爬虫进行数据爬取,还是使用现有的付费数据接口呢?本文将从成本、可靠性、数据质量等多个角度进行分析&#xf…

深入学习 Redis - 事务、实现原理、指令使用及场景

目录 一、Redis 事务 vs MySQL事务 二、Redis 事务的执行原理 2.1、执行原理 2.2、Redis 事务设计这么简单,为什么不涉及成 MySQL 那样强大呢? 三、Redis 事务的使用 3.1、使用场景 3.2、具体演示 开启/执行/放弃事务 watch 监控 watch 实现原理…

Dockerfile部署golang

使用go镜像打包,运行在容器内 redis和mysql用外部的 项目目录结构 w1go项目: Dockerfile # 这种方式是docker项目加上 本地的mysql和redis环境 # go打包的容器 FROM golang:alpine AS builder# 为我们镜像设置一些必要的环境变量 ENV GO111MODULEon …

Nginx可视化NginxWebUI

Nginx可视化Web Github:https://github.com/cym1102/nginxWebUI 支持window、linux 安装方式支持docker、window直接运行 jar包cmd运行:port可自行替换 java -jar -Dfile.encodingUTF-8 D:/软件/Nginx-Ui/nginxWebUI-3.6.3.jar --server.port8380 --project.hom…

centos7 yum源安装出错及更新问题

如下 首先,在搜索jdk时报错如下: 解决办法 1、进入 yum的repo目录 cd /etc/yum.repos.d/2、修改所有的CentOS文件内容 sed -i s/mirrorlist/#mirrorlist/g /etc/yum.repos.d/CentOS-*sed -i s|#baseurlhttp://mirror.centos.org|baseurlhttp://vau…

HDFS集群滚动升级以及回滚相关

HDFS集群滚动升级以及回滚相关 介绍不停机滚动升级非联邦HA集群联邦HA集群 停机升级--非HA集群HDFS集群降级和回滚异同点共同点不同点 HA集群降级(downgrade)注意事项 集群回滚操作 介绍 在hadoop v2中,HDFS支持namenode高可用(H…

Benchmarking Augmentation Methods for Learning Robust Navigation Agents 论文阅读

论文信息 题目:Benchmarking Augmentation Methods for Learning Robust Navigation Agents: the Winning Entry of the 2021 iGibson Challenge 作者:Naoki Yokoyama, Qian Luo 来源:arXiv 时间:2022 Abstract 深度强化学习和…

java.util.NoSuchElementException: No value present-报错(已解决)

阿丹: 今天在spring-boot整合MongoDB的过程中出现了下面的错误,是因为追求新技术、更优雅产生的。 记录一下。 错误截图如下: 错误位置代码如下: 主要问题(问题原因): 因为之前升级了我的jdk的…

Red Hat 安装MySQL 8.0与 Navicat

目录 Red Hat 安装 MySQL 8.0 1、更新软件包列表 2、安装MySQL服务器和客户端 3、启动MySQL服务 4、确保MySQL服务器正在运行 5、root 用户的密码 6、登录MySQL,输入mysql密码 7、MySQL默认位置 Red Hat 安装 Navicat 1、下载 Navicat 2、执行命令 Red H…

布基纳法索ECTN(BESC)申请流程

根据BURKINA FASO布基纳法索签发于 11/07/2006法令编号 00557的规定: 自2006年11月07 日起所有出口至布基纳法索(Burkina Faso)的货物,必须申请ECTN/BESC。ECTN是ELECTRONIC CARGO TRACKING NOTE的英文缩写,BESC是BORDEREAU DE SU…

Maven分模块-继承-聚合-私服的高级用法

Maven分模块-继承-聚合-私服的高级用法 JavaWeb知识,介绍Maven的高级用法!!! 文章目录 Maven分模块-继承-聚合-私服的高级用法1. 分模块设计与开发1.1 介绍1.2 实践1.2.1 分析1.2.2 实现 1.3 总结 2. 继承与聚合2.1 继承2.1.1 继承…

vue2中使用mock数据发送请求

1.安装 npm i mockjs1.1 2.准备json数据 说明:mock数据需要的图片放置到public文件夹中(原封不动的打包到dist文件夹) [{"id": "1","imgUrl": "/images/banner1.jpg"},{"id": "2&qu…

python excel 操作

excel文件内容如下: 一、xlrd 读Excel 操作 1、打开Excel文件读取数据 filexlrd.open_workbook(filename)#文件名以及路径,如果路径或者文件名有中文给前面加一个 r 2、常用函数 (1)获取一个sheet工作表 table file.sheets(…

C++11 新特性 ---- 原始字面量

一、原始字面量 R “xxx(原始字符串)xxx”&#xff0c;其中&#xff08;&#xff09;两边的字符串可以省略。 #include <iostream> #include <string> using namespace std; int main() {string str1 R"(D:\hello\heheda\test.txt)";string str2 R&q…

day1-牛客67道剑指offer-JZ4 JZ6 JZ7 JZ9 JZ11 JZ69 JZ70 替换空格 斐波那契数列及其变形 左移/右移运算符

文章目录 1. JZ4 二维数组中的查找暴力法右上角往左下角逼近二分查找-左闭右开区间 2. 替换空格3. JZ6 从尾到头打印链表4. JZ7 重建二叉树思路1哈希加速 5. JZ9 用两个栈实现队列6. JZ11 旋转数组的最小数字常规遍历二分法 7. 斐波那契数列动态规划递归 8. JZ69 跳台阶动态规划…

Swintransformer模型的优化

SwinTransformer模型优化 文章目录 SwinTransformer模型优化1.SwinTransformer概述2.性能瓶颈分析3.模型优化3.1.transpose消除3.2.更好的layergroup3.1.1.SliceOp3.1.2.SqueezeOp3.1.3.weight切分 4.优化效果 1.SwinTransformer概述 自从Transformer在NLP任务上取得突破性的进…

UE5 半透明覆层材质

文章目录 前言介绍示例1示例2示例3 前言 本文采用虚幻5.2.1版本演示&#xff0c;介绍半透明覆层材质&#xff08;覆层材质&#xff09;。 介绍 半透明覆层材质是 UE5.1 版本 更新的功能&#xff0c;使用半透明覆层材质&#xff0c;可以轻松的给物体表面附着一层材质。 在UE5…

[IDEA]使用idea比较两个jar包的差异

除了一些小工具外&#xff0c;idea自带了jar包比较的功能。 把需要比对的jar包放到任意目录下&#xff0c;然后选中两个需要比较的jar包&#xff0c;右键&#xff0c;选择Compare Archives&#xff0c;然后就可以比较了。 这次疏忽了&#xff0c;每次打包前需要commit界面看一下…

Unity 编辑器选择器工具类Selection 常用函数和用法

Unity 编辑器选择器工具类Selection 常用函数和用法 点击封面跳转下载页面 简介 在Unity中&#xff0c;Selection类是一个非常有用的工具类&#xff0c;它提供了许多函数和属性&#xff0c;用于操作和管理编辑器中的选择对象。本文将介绍Selection类的常用函数和用法&#xff…

untiy 连接两个UI或一段固定一段跟随鼠标移动的线段

注意&#xff0c;仅适用于UI&#xff0c;且Canvas必须是Camera模式&#xff0c;不能用在3D物体上&#xff0c;3D物体请使用LineRenender 先创建一个图片&#xff0c;将锚点固定在左边 然后在脚本中添加如下内容 public RectTransform startObj;//起点物体public RectTransfor…