ElasticSearch全文检索和倒排索引

本文内容参考了田雪松老师编著的《Elastic Stack应用宝典

全文检索

先来解释一下什么叫全文检索。数据检索的目的是从一系列数据中,根据某一或某些数据特征将特定的数据找出来。从数据检索的角度来看,数据大体上可以分为两种类型:一种是结构化数据;另一种是非结构化数据。结构化数据将数据具有的特征事先以结构化的形式定义好,数据有固定的格式或有限的长度。典型的结构化数据就是传统关系型数据库的表结构,数据特征直接体现在表结构的字段上,所以根据某一特征做数据检索很直接,速度也比较快。比如,根据商品的名称将该商品全部查找出来,通过一条SQL语句就能实现。如果想要提高查找速度,只要在商品名称上创建索引就可以了。许多应用系统都是建立在结构化数据的基础之上,例如财务软件、CRM、MIS等。

非结构化数据则完全不同,它们没有预先定义好的结构化特征,也没有固定格式和固定长度。典型的非结构化数据包括文章、图片、视频、网页、邮件等,其中像HTML网页这种具有一定格式的文档也称为半结构化数据。显而易见,相比结构化数据,非结构化数据的检索要难得多。在对它们的检索中,像文章、网页、邮件这种全文本(Full-text)数据的检索需求占了大多数,而且与图片、视频等非文本数据的检索完全不同,因此形成了一门独立的学科,这就是全文检索。包括Elastic官方网站在内的很多文献中,经常称全文本数据为全文数据,称全文数据中的一条数据为文档(Document)​,而称存储全文数据的数据库为全文数据库。所以简单来说,全文检索是指在全文数据中检索单个文档或文档集合的搜索技术,而Elasticsearch从这个意义上来说也可以理解为是一个全文数据库。

与结构化查询相比,全文检索面临的最大问题就是性能问题。全文检索最一般的应用场景是根据一些关键字查找包含这些关键字的文档,比如互联网搜索引擎要实现的功能就是根据一些关键字查找网页。显然,如果没有对文档做特别处理,查找的办法似乎只能是逐条比对。具体来说就是先将所有文档都读取出来,再对文档内容做逐行扫描看是否包含这些关键字。例如,Linux中的grep命令就是通过这种算法实现的。但这种方法在数据量非常大的情况下就像海底捞针一样,速度一定会非常慢。而类似互联网搜索引擎这样的应用面对的文档数量往往都是天文数字,所以需要有一种更好的办法实现全文检索。

关系型数据库提升数据查询速度的常用方法是给字段添加索引,有了索引的字段会根据字段值排序并创建类似排序二叉树的数据结构(如B树)​,这样就可以利用二分查找等算法提升查询速度。所以在字段添加索引后,通过这些字段做查询时速度能够得到非常明显的提升。但由于添加索引后需要对字段排序,所以增加和删除数据时速度会变慢,并且还需要额外的空间存储索引。这是典型的利用空间换取时间的策略。普通的索引对全文检索并不适用,因为这种索引使用字段整体值参与排序,所以在检索时也要通过字段的整体值做查询条件。而全文检索一般是查询包含某一或某些关键字的文档,所以通过文档整体值建立的索引对提高查询速度是没有任何帮助的。为了解决这个问题,人们创建了一种新索引方法,这种索引方法就是倒排索引(Inverted Index)​。

倒排索引

倒排索引先将文档中包含的关键字全部提取出来,然后再将关键字与文档的对应关系保存起来,最后再对关键字本身做索引排序。用户在检索某一关键字时,可以先对关键字的索引进行查找,再通过关键字与文档的对应关系找到所在文档。这类似于查字典一样,字典的拼音表和部首表就是关键字索引,而拼音表和部首表中的内容就是关键字与文档的对应关系。

有了倒排索引,用户检索就可以在倒排索引中快速定位到包含关键字的文档。倒排索引与关系型数据库索引类似,会根据关键字做排序。但关系型数据库索引一般是对主键创建,然后索引指向数据内容;而倒排索引则正好相反,它是针对文档内容创建索引,然后索引指向主键(文档一、文档二)​,这就是这种索引被称为倒排索引的原因。

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

相关推荐
成长的小牛2333 小时前
es使用knn向量检索中numCandidates和k应该如何配比更合适
大数据·elasticsearch·搜索引擎
Elastic 中国社区官方博客4 小时前
Elasticsearch:什么是查询语言?
大数据·数据库·elasticsearch·搜索引擎·oracle
yaosheng_VALVE5 小时前
探究全金属硬密封蝶阀的奥秘-耀圣控制
运维·eclipse·自动化·pyqt·1024程序员节
dami_king5 小时前
SSH特性|组成|SSH是什么?
运维·ssh·1024程序员节
AI_Mind12 小时前
Gemini 2.0:面向智能体时代的全新 AI 模型
人工智能·搜索引擎
幽弥千月14 小时前
【ELK】ES单节点升级为集群并开启https【亲测可用】
elk·elasticsearch·https
IT猿手14 小时前
基于PWLCM混沌映射的麋鹿群优化算法(Elk herd optimizer,EHO)的多无人机协同路径规划,MATLAB代码
算法·elk·机器学习·matlab·无人机·聚类·强化学习
jingling5551 天前
如何使用免费资源--知网篇
开发语言·经验分享·搜索引擎·pdf·开源
酱学编程1 天前
ES搜索原理
大数据·elasticsearch·搜索引擎
流穿1 天前
ELK系列-(六)Redis也能作为消息队列?(下)
数据库·redis·ubuntu·elk·docker·容器