全文检索

726 阅读3分钟

全文检索

数据分类:

  • 结构化数据: 固定格式,有限长度 比如mysql存的数据
  • 非结构化数据:不定长,无固定格式 比如邮件,word文档,日志
  • 半结构化数据: 前两者结合 比如xml,html

搜索分类:

  • 结构化数据搜索: 使用关系型数据库
  • 非结构化数据搜索
    • 顺序扫描
    • 全文检索

设想一个关于搜索的场景,假设我们要搜索一首诗句内容中带“前”字的古诗

namecontentauthor
静夜思床前明月光,疑是地上霜。举头望明月,低头思故乡。李白
望庐山瀑布日照香炉生紫烟,遥看瀑布挂前川。飞流直下三千尺,疑是银河落九天。李白
.........

思考:用传统关系型数据库和ES 实现会有什么差别?

如果用像 MySQL 这样的 RDBMS 来存储古诗的话,我们应该会去使用这样的 SQL 去查询

select name from poems where content like "%前%"

这种我们称为顺序扫描法,需要遍历所有的记录进行匹配。不但效率低,而且不符合我们搜索时的期望,比如我们在搜索“ABCD"这样的关键词时,通常还希望看到"A","AB","CD",“ABC”的搜索结果。

什么是全文检索

全文检索是指:

  • 通过一个程序扫描文本中的每一个单词,针对单词建立索引,并保存该单词在文本中的位置、以及出现的次数
  • 用户查询时,通过之前建立好的索引来查询,将索引中单词对应的文本位置、出现的次数返回给用户,因为有了具体文本的位置,所以就可以将具体内容读取出来了

clipboard (9).png

搜索原理简单概括的话可以分为这么几步:

  • 内容爬取,停顿词过滤比如一些无用的像"的",“了”之类的语气词/连接词
  • 内容分词,提取关键词
  • 根据关键词建立倒排索引
  • 用户输入关键词进行搜索

倒排索引

索引就类似于目录,平时我们使用的都是索引,都是通过主键定位到某条数据,那么倒排索引呢,刚好相反,数据对应到主键。

截图 (2).png

这里以一个博客文章的内容为例:

正排索引(正向索引)

文章ID文章标题文章内容
1浅析JAVA设计模式JAVA设计模式是每一个JAVA程序员都应该掌握的进阶知识
2JAVA多线程设计模式JAVA多线程与设计模式结合

倒排索引(反向索引)

假如,我们有一个站内搜索的功能,通过某个关键词来搜索相关的文章,那么这个关键词可能出现在标题中,也可能出现在文章内容中,那我们将会在创建或修改文章的时候,建立一个关键词与文章的对应关系表,这种,我们可以称之为倒排索引。

like %java设计模式% java 设计模式

关键词文章ID
JAVA1,2
设计模式1,2
多线程2

简单理解,正向索引是通过key找value,反向索引则是通过value找key。ES底层在检索时底层使用的就是倒排索引。