全文检索
数据分类
结构化数据
结构化数据就是具有固定格式和长度的数据,比如数据库,元数据等,对于结构化数据,可以通过关系型数据库(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 也是正排索引
倒排索引
倒排索引也非常的简单,就是正排索引反过来,当然不是直接反过来,而是这样子,因为倒排索引这种结构,导致它的查询效率那是非常滴快
看到这里可能有的朋友有疑问了,ElasticSearch 是怎么把关键字,词提取出来的呢?这就靠 ElasticSearch 中内置的一些分词器了,这些分词器会对我们存储的文字进行处理,转大小写、去空格、过滤、切分等等等等,都是由分词器进行完成的,
ElasticSearch 与 MySQL 存储数据对应关系
下面这张图片是 ElasticSearch 和 MySQL存储数据的概念进行一个对比
索引(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集成使用教程
我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿。