ElasticSearch的倒排索引和相关概念
在用关系型数据库时,一些频繁用作查询条件的字段我们都会去建立索引来提升查询效率。在关系型数据库中,我们一般都采用 B 树索引进行存储,所以 B 树索引也是我们接触比较多的一种索引数据结构,但是在使用过程中,我们发现无法使用关系型数据库进行类似与搜索引擎那般强大的多关键字查询,就比如说通常我们在使用搜索引擎时经常会使用小米 手机
这样子的文本表示,但在sql语句中通常以这种形式表示:
select * from item where name like '%小米 手机%';
可能看出来效果并不是我们想要展示出来的效果,因此我们需要一个可以实现复杂搜索的全文检索服务器,他就是ElasticSearch,它通过倒排索引可以实现复杂查询,那么什么时倒排索引呢,和正排索引有什么区别呢?
- 正排索引是指文档ID为key,表中记录每个关键词出现的次数,查找时扫描表中的每个文档中字的信息,直到找到所有包含查询关键字的文档。
对于关系型数据库,例如mysql中,可以清晰的看出我们的id是作为主键使用的,通过主键可以定位某一条数据,但是如果想要使用其他字段进行查找是,就需要遍历整张表进行比较,效率比较低。
如图,这就是典型的正排索引。通过id等唯一键能够精确的定位到某条数据,但是想通过name,price,却需要遍历查询整张表。
- 倒排索引就是指,通过拆分将文档中的内容拆成一个个独立的单词,在通过这些单词和他们所属的id形成一张以不重复的分词为key,id为属性的表,可以通过分词快速定位,然后找到存在这些词的id,再去正排索引那以id查询全部信息
可以看到我们把上表拆分成了多张表,但是我们却可以根据原表中的字段快速定位到包含这些分词的id号,从而可以在原表中查询全部详细信息
其中:- 词条(Term):索引里面最小的存储和查询单元,对于英文来说是一个单词,对于中文来说一般指分词后的一个词。
- 词典(Term Dictionary):或字典,是词条Term的集合。搜索引擎的通常索引单位是单词,单词词典是由文档集合中出现过的所有单词构成的字符串集合,单词词典内每条索引项记载单词本身的一些信息以及指向“倒排列表”的指针。
- 倒排表(Post list):一个文档通常由多个词组成,倒排表记录的是某个词在哪些文档里出现过以及出现的位置。每条记录称为一个倒排项(Posting)。倒排表记录的不单是文档编号,还存储了词频等信息。
- 倒排文件(Inverted File):所有单词的倒排列表往往顺序地存储在磁盘的某个文件里,这个文件被称之为倒排文件,倒排文件是存储倒排索引的物理文件。
这时候,如果我们进行搜索小米手机
时,分词器会拆分为小米
和手机
,去倒排索引表中查询,会得到三条数据,其中小米手机
命中两次,小米电脑
和华为手机
都命中一次,使用小米手机
会排在第一位,剩下两个就会排在下面,就做到了类似于搜索引擎的复杂查询。
总结:
正排索引和倒排索引都适用于所有的数据库,其中,正排索引更适合使用唯一键快速定位结果,倒排索引更适合复杂查询,类似于查找文档中是否存在某些关键字等,得到包含这些关键字的文件索引,再通过正排索引快速定位文件,最后实现查找文档的功能。
关于分词器的选择,默认的分词器会对于英文,以单词拆分,关于汉字,会一个字一个字的拆分,
可以使用IK分词器
IK分词器:可以进行扩展词,也可以进行停用词,其中ik分词器具有两种模式:
ik_smart:粗粒度切分,分出来的词少
ik_max_word:细粒度切分,分出来的词多
ES相关概念对比MySQL
ES和mMysql的关系如下图所示
其中:
- 类型就相当于MySql里的表,我们知道MySql里一个库下可以有很多表,最原始的时候ES也是这样,一个索引下可以有很多类型,但是从6.0版本开始,type已经被逐渐废弃,但是这时候一个索引仍然可以设置多个类型,一直到7.0版本开始,一个索引就只能创建一个类型了(_doc)。这一点,大家要注意,网上很多资料都是旧版本的,没有对这点进行说明。
- 一个数据库表(Table)下的数据由多行(ROW)多列(column,属性)组成,对于ES来说,一个index下存在多个文档(Document)和多Field组成。
- MySql中一个行(row)中包含多个字段(column),ES中一个文档中也存在多个分词(Field).
- 一个关系型数据库里面,schema定义了表、每个表的字段,还有表和字段之间的关系。与之对应的,在ES中:Mapping定义索引下的Type的字段处理规则,即索引如何建立、索引类型、是否保存原始索引JSON文档、是否压缩原始JSON文档、是否需要分词处理、如何进行分词处理等。
- 在数据库中的增insert、删delete、改update、查search操作等价于ES中的增改PUT、删Delete、改update、查GET。
注意:ES中不能修改以及提交的分词字段,只能增加。