一、先认识下关系型数据库的全文搜索
搜索的核心诉求就是全文搜索,全文搜索简单来说就是要在大量文档中找到匹配指定条件出现的位置。在关系型数据库中,数据检索只能通过关键字like实现,左右或中间模糊查询。
举例: select * from company where name like “%斗罗大陆%”; select * from company where name like “%斗罗大陆”; select * from company where name like “斗罗大陆%”; |
这种方式的实现存在的问题:
- 无法使用数据库索引,需要全表扫描,性能差。
- 搜索效果差,只能首位模糊匹配,无法实现复杂的搜索需求。
- 无法得到文档域搜索条件的相关性。
搜索的核心目标实际上就是保证搜索的效果和性能,为了高效的实现全文索引,Elasticsearch通过倒排索引来解决。
二、正排索引和倒排索引
2.1、概念
正排索引:指的是以文档对象的唯一id作为索引,以文档内容作为记录的结构。
倒排索引:指的是以文档内容的单词作为索引,将包含改词的文档iD作为记录的结构。
看三句话生成的倒排索引过程:
Term index:词项索引
Term dictionary: 词项字段
Post listing: 倒排列表
2.2、词典数结构(trie->prefix tree(前缀树))
加入依次插入:hello, hello word, hello china, welcome。结果会如下,如果单词前缀相同会匹配前面已建立的节点(深绿色是单词结尾),
演示地址:https://www.cs.usfca.edu/~galles/visualization/Trie.html。
2.3、使用倒排索引的搜索过程
假设现有几条数据,如下:
正排索引结构如下:
文档id | 文档内容 |
1 | 欧美金融城澳洲中心 |
2 | 欧美金融城英国中心 |
生成倒排索引:
- 首先要对字段的内容进行分词,分词就是将一段连续的文本按照语义分为多个单词,这里两个文档包含的关键词有:“欧美金融城华夏之心”,“欧美金融城英国中心”。
- 然后按照单词来作为索引,去重之后,对应的与文档id建立一个链表,就能组成上诉的倒排索引结构。
单词 | 文档id |
欧美 | 1,2 |
金融城 | 1,2 |
澳洲 | 1 |
英国 | 2 |
中心 | 1,2 |
搜索过程: