"搜索引擎"对于很多大厂来说已经不是什么新鲜技术了, 百度、淘宝等大型网站的搜索功能通常使用"搜索引擎"技术实现。 "搜索引擎"到底做了什么? 它和普通的数据库搜索有什么区别? 什么情况下才需要使用"搜索引擎"? 带着这些疑问,我们开始【对"搜索引擎"的探索】 "搜索"的本质其实是对"数据"的处理,所以我们先从"数据讲起"数据类型 以搜索的角度划分,数据分为两种:结构化数据、非结构化数据(全文数据) 结构化数据:具有固定格式或有限长度的数据,就像我们用的数据库(创建字段必须指定格式) 非结构化数据:指不定长度或无固定格式的数据,如邮件、word文档 于是衍生出两种搜索类型 对结构化数据的搜索:也就是我们平时用的最多的,对数据库的SQL搜索,名称、状态、创建时间等 举个例子来说,我们假设公众号将我的文章信息存到了这样一张表中 table: id title author filepath(文章内容的文件上传之后返回的保存路径) createtime 当我想要查询标题中包含"搜索"的文章,一个SQL就可以SELECT * from table where title like "%搜索%" 这样就完成了一次结构化数据的搜索, 另一种就是对非结构化数据的搜索:即对邮件、word文档等做内容搜索 还是上面的例子,但这次我们希望搜索文章内容中包含"搜索"的文章,你会怎么做呢? 按照上面结构化数据的搜索思路,遍历数据库中所有的filepath,通过filePath获取到文章文件本体,将文章内容从头到尾扫描一遍,直到将所有文件都扫描完,返回匹配结果。 这种顺序扫描法想必不用说你也能想到效率问题,如果我有成千上万个文件,每个文件包含上千字,扫描量可想而知。 全文检索 既然顺序扫描法不可取,我们是否可以换个思路:将非结构化的数据中的一部分信息提取出来,然后以某种规则重组,使其变得有一定的结构,然后对此结构数据建立索引并进行搜索,从而达到快速搜索的目的。 这种将非结构化数据拆分、结构化,建立索引并对索引进行搜索的搜索方式就叫做全文检索,即"搜索引擎"的设计思想。 就像是文字和字典的关系,字典的拼音表和部首检字表就相当于字典的索引,对每一个字的解释是非结构化的,如果字典没有音节表和部首检字表,在茫茫辞海中找一个字只能顺序扫描。 然而字的某些信息可以提取出来进行结构化处理,比如读音,就比较结构化,分声母和韵母,分别只有几种可以一一列举,于是将读音拿出来按一定的顺序排列,每一项读音都指向此字的详细解释的页数。 我们搜索时按结构化的拼音搜到读音,然后按其指向的页数,便可找到我们的非结构化数据——也即对字的解释。 还记得上面搜索文章内容的问题吗,我们试着用全文检索模拟一下: 假设现在我有100篇文章(编号0~100),我需要找出内容中包含"搜索"、"引擎"两个关键字的文章, 首先根据这两个词汇建立索引结构: 左边保存的是一系列字符串,称为词典 。 每个字符串都指向包含此字符串的文档(Document)链表,此文档链表称为倒排表 (Posting List)。 这样一来,我们只需要将"搜索"、"引擎"两个链表做合并,即可得到搜索结果。 值得注意的是,虽然创建索引的过程和顺序扫描是一样的,但区别在于顺序扫描是每次都要扫描,而创建索引的过程仅仅需要一次,以后便是一劳永逸,仅需要搜索创建好的索引即可。 这也是全文搜索相对于顺序扫描的优势之一:一次索引,多次使用。 以上就是本篇的内容,通过今天的内容我们了解了"搜索引擎"到底做了什么、它和普通的数据库搜索有什么区别、什么情况下才需要使用"搜索引擎"。下期预告 下一篇我们将深入拆解"搜索"引擎如何创建索引?为什么在输入了错别字的情况下,百度依然返回了正确的搜索结果? 更多干活内容尽在同名公众号:浩说编程,欢迎互相交流