全文检索
数据分类:
- 结构化数据: 固定格式,有限长度 比如mysql存的数据
- 非结构化数据:不定长,无固定格式 比如邮件,word文档,日志
- 半结构化数据: 前两者结合 比如xml,html
搜索分类:
- 结构化数据搜索: 使用关系型数据库
- 非结构化数据搜索
-
- 顺序扫描
- 全文检索
设想一个关于搜索的场景,假设我们要搜索一首诗句内容中带“前”字的古诗
| name | content | author |
| 静夜思 | 床前明月光,疑是地上霜。举头望明月,低头思故乡。 | 李白 |
| 望庐山瀑布 | 日照香炉生紫烟,遥看瀑布挂前川。飞流直下三千尺,疑是银河落九天。 | 李白 |
| ... | ... | ... |
思考:用传统关系型数据库和ES 实现会有什么差别?
如果用像 MySQL 这样的 RDBMS 来存储古诗的话,我们应该会去使用这样的 SQL 去查询
select name from poems where content like "%前%"
这种我们称为顺序扫描法,需要遍历所有的记录进行匹配。不但效率低,而且不符合我们搜索时的期望,比如我们在搜索“ABCD"这样的关键词时,通常还希望看到"A","AB","CD",“ABC”的搜索结果。
什么是全文检索
全文检索是指:
- 通过一个程序扫描文本中的每一个单词,针对单词建立索引,并保存该单词在文本中的位置、以及出现的次数
- 用户查询时,通过之前建立好的索引来查询,将索引中单词对应的文本位置、出现的次数返回给用户,因为有了具体文本的位置,所以就可以将具体内容读取出来了
搜索原理简单概括的话可以分为这么几步:
- 内容爬取,停顿词过滤比如一些无用的像"的",“了”之类的语气词/连接词
- 内容分词,提取关键词
- 根据关键词建立倒排索引
- 用户输入关键词进行搜索
倒排索引
索引就类似于目录,平时我们使用的都是索引,都是通过主键定位到某条数据,那么倒排索引呢,刚好相反,数据对应到主键。
这里以一个博客文章的内容为例:
正排索引(正向索引)
| 文章ID | 文章标题 | 文章内容 |
| 1 | 浅析JAVA设计模式 | JAVA设计模式是每一个JAVA程序员都应该掌握的进阶知识 |
| 2 | JAVA多线程设计模式 | JAVA多线程与设计模式结合 |
倒排索引(反向索引)
假如,我们有一个站内搜索的功能,通过某个关键词来搜索相关的文章,那么这个关键词可能出现在标题中,也可能出现在文章内容中,那我们将会在创建或修改文章的时候,建立一个关键词与文章的对应关系表,这种,我们可以称之为倒排索引。
like %java设计模式% java 设计模式
| 关键词 | 文章ID |
| JAVA | 1,2 |
| 设计模式 | 1,2 |
| 多线程 | 2 |
简单理解,正向索引是通过key找value,反向索引则是通过value找key。ES底层在检索时底层使用的就是倒排索引。