来花5分钟了解下全文检索,以及什么是ElasticSearch吧!

378 阅读6分钟

全文检索

数据分类

结构化数据

结构化数据就是具有固定格式和长度的数据,比如数据库,元数据等,对于结构化数据,可以通过关系型数据库(mysql、oracle)存储和搜索,也可以建立索引。通过b-tree等数据结构快速搜索数据

非结构化数据

全文数据,指不定长或无固定格式的数据,如邮件,word,图片,视频等。这些数据结构不规则,无法用关系型数据库存储的就是非结构化数据了。
对于非结构化数据,也即对全文数据的搜索主要有两种方式:顺序扫描法,全文检索

顺序扫描法

所谓顺序扫描,比如要找内容包含某一个字符串的文件,就是一个文档一个文档的看,对于每一个文档,从头看到尾,如果此文档包含此字符串,则此文档为我们要找的文件,接着看下一个文件,直到扫描完所有的文件。
这种检索方式毫无疑问是效率最低的,当一个文章几万字的时候,有几十万篇这样的文章,一个一个扫描需要多少时间,在实际当中,我们有时候会使用Mysql来存储文档数据,但是当我们通过关键字来进行模糊查询的时候,那惊人的效率足以让人落泪,有时间的小伙伴可以去试试哈。

全文检索

上面说到非结构化的数据检索很慢,但是有什么办法可以解决这个问题呢?

我们知道结构化数据检索是很快的,那么我们就想办法让这个非结构化数据转为结构化数据,不就可以完美解决这个问题了吗。

到这里问题又来了,我们怎么来将这个非结构化的数据转为结构化的数据呢?

可以这样,我们把非结构化数据中的一些信息提取出来,然后将其以结构化的形式存储起来,当我们进行搜索的时候,我们可以去搜索结构化的数据来去找到那些非结构化数据。

说到这里可能你还不是很清晰,这里举个例子说明下吧 以上面说到文章举例,当我们存储文章内容比较长,文章篇数又比较多的时候,我们可以将文章内容的各个关键字词组提取出来,以结构化的形式存储。现在有文章A和文章B,直接简称A和B了,A中有明天这两个字,b中也有明天两个字,我们可以这样,以明天作为主键/key,对应文章的id作为值/内容,来进行存储。

这样当我们搜索明天的时候,我们可以通过明天来搜索到所有包含明天这个词的文章Id,然后拿到这个文章Id,再去查询到文章内容,这样可以极大的提升查询的效率。


总结

全文检索就是计算机扫描文章中的每一个词,对其构建索引,当用户查询的时候,建立的索引快速查找。

ElasticSearch 简介

Elasticsearch 是一个RESTful 风格的实时的分布式存储、搜索和数据分析引擎

为什么要使用 ElasticSearch 呢

上接全文检索的那个例子,当使用数据库查询比较慢的时候,我们就需要使用全文检索的方式来进行检索了,而 ElasticSearch 就是一个全文搜索引擎,他相较于数据库,强大之处就是可以快速的进行模糊查询,解决上述问题,然后就是从 ElasticSearch 中搜索到的数据可以根据评分过滤掉大部分,只返回给用户评分高的就可以了,原生就支持排序,还可以匹配相关的记录,即使输入的关键字不那么准确,也能找到相关的结果。

ElasticSearch 为什么查询很快的,是因为他使用了一个特殊的概念来保证查询速度,它就是倒排索引 有了倒排索引,那么肯定有一个概念叫正排索引,下面简单说一下这两种索引都是怎么一回事

正排索引

这个就很简单了,在生活中我们书籍的目录就是正排索引(每个页码都对应着相应的内容),还有数据库中 id --- value 也是正排索引

倒排索引

倒排索引也非常的简单,就是正排索引反过来,当然不是直接反过来,而是这样子,因为倒排索引这种结构,导致它的查询效率那是非常滴快

image.png

看到这里可能有的朋友有疑问了,ElasticSearch 是怎么把关键字,词提取出来的呢?这就靠 ElasticSearch 中内置的一些分词器了,这些分词器会对我们存储的文字进行处理,转大小写、去空格、过滤、切分等等等等,都是由分词器进行完成的,

ElasticSearch 与 MySQL 存储数据对应关系

下面这张图片是 ElasticSearch 和 MySQL存储数据的概念进行一个对比 image.png

索引(index):

一个索引可以理解为一个数据库

类型(type):

一个type可以理解为一张表,不过 ElasticSearch7.X 以后就已经移除了这个概念

移除原因:设计的初衷是为了管理数据之间的关系,后来大家都觉得 type相当于一个数据表,但是关系数据库中的表是独立的,里面有相同的列也不影响使用,但在 ElasticSearch 中不是这样的 ElasticSearch 是基于 Lucene 开发的搜索引擎,在 ElasticSearch 中不同type下名称相同的 filed 最终在 Lucene 中处理的方式是一样的,两个不同 type 下的字段,在 ElasticSearch 同一个索引下被认为是相同的diled,定义的时候必须要避免这个问题,否则就会出现冲突,影响效率。

映射(mapping):

mapping定义了每个字段的类型等信息。相当于关系型数据库中的表结构

文档(document):

一个document相当于关系型数据库中的一行记录

字段(field):

相当于关系型数据库表的字段

集群(cluster):

  集群由一个或多个节点组成,一个集群由一个默认名称“elasticsearch”

节点(node):

  集群的节点,一台机器或者一个进程

分片和副本(shard):

  • 副本是分片的副本。分片有主分片(primary Shard)和副本分片(replica Shard)之分
  • 一个Index数据在屋里上被分布在多个主分片中,每个主分片只存放部分数据
  • 每个主分片可以有多个副本,叫副本分片,是主分片的复制

这次介绍就先写到这里吧,相信你也知道ElasticSearch是个什么了,集群的话还没仔细研究,现在我用到的是单节点的,下一篇会出一篇SpringBoot集成使用教程

我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿