原创

深入拆解'搜索引擎'实现原理一:初识 '搜索引擎'

作者 | 浩说编程
来源 | 公众号:浩说编程
[  用"内容"服务读者 | 让"代码"服务大众  ]


'搜索引擎'对于很多大厂来说已经不是什么新鲜技术了,
百度、淘宝等大型网站的搜索功能通常使用'搜索引擎'技术实现。
'搜索引擎'到底做了什么?
它和普通的数据库搜索有什么区别?
什么情况下才需要使用'搜索引擎'?
带着这些疑问,我们开始【对'搜索引擎'的探索】

    '搜索'的本质其实是对'数据'的处理,所以我们先从'数据'讲起


01 | 数据类型

    以搜索的角度划分,数据分为两种:结构化数据、非结构化数据(全文数据)

  1. 结构化数据:具有固定格式或有限长度的数据,就像我们用的数据库(创建字段必须指定格式)

  2. 非结构化数据:指不定长度或无固定格式的数据,如邮件、word文档

    于是衍生出两种搜索类型

        1、对结构化数据的搜索:也就是我们平时用最多的,对数据库的SQL搜索,名称、状态、创建时间等

        举个例子来说,我们假设公众号将我的文章信息存到了这样一张表中

        table:   id title author filepath(文章内容的文件上传之后返回的保存路径) createtime

        当我想要查询标题中包含'搜索'的文章,一个SQL就可以:

SELECT * from table where title like '%搜索%'

          这样就完成了一次结构化数据的搜索。

        2、另一种就是对非结构化数据的搜索:即对邮件、word文档等做内容搜索

        还是上面的例子,但这次我们希望搜索文章内容中包含'搜索'的文章,你会怎么做呢?

        按照上面结构化数据的搜索思路,遍历数据库中所有的filepath,通过filePath获取到文章文件本体,将文章内容从头到尾扫描一遍,直到将所有文件都扫描完,返回匹配结果。

        这种顺序扫描法想必不用说你也能想到效率问题,如果我有成千上万个文件,每个文件包含上千字,扫描量可想而知。


02 | 全文检索

    既然顺序扫描法不可取,我们是否可以换个思路:

    将非结构化的数据中的一部分信息提取出来,然后以某种规则重组,使其变得有一定的结构,然后对此结构数据建立索引并进行搜索,从而达到快速搜索的目的。

    这种将非结构化数据拆分、结构化,建立索引并对索引进行搜索的搜索方式就叫做全文检索,即'搜索引擎'的设计思想。

    就像是文字和字典的关系,字典的拼音表和部首检字表就相当于字典的索引,对每一个字的解释是非结构化的,如果字典没有音节表和部首检字表,在茫茫辞海中找一个字只能顺序扫描。

    然而字的某些信息可以提取出来进行结构化处理,比如读音,就比较结构化,分声母和韵母,分别只有几种可以一一列举,于是将读音拿出来按一定的顺序排列,每一项读音都指向此字的详细解释的页数。

    我们搜索时按结构化的拼音搜到读音,然后按其指向的页数,便可找到我们的非结构化数据——也即对字的解释。

    还记得上面搜索文章内容的问题吗?我们试着用全文检索模拟一下:

    假设现在我有100篇文章(编号0~100),我需要找出内容中包含'搜索'、'引擎'两个关键字的文章,

    首先根据这两个词汇建立索引结构


深入拆解'搜索引擎'实现原理一:初识 '搜索引擎'


    左边保存的是一系列字符串,称为词典 。

    每个字符串都指向包含此字符串的文档(Document)链表,此文档链表称为倒排表 (Posting List)。

    这样一来,我们只需要将'搜索'、'引擎'两个链表做合并,即可得到搜索结果:


深入拆解'搜索引擎'实现原理一:初识 '搜索引擎'


    值得注意的是:虽然创建索引的过程和顺序扫描是一样的,但区别在于顺序扫描是每次都要扫描,而创建索引的过程仅仅需要一次,以后便是一劳永逸,仅需要搜索创建好的索引即可。

这也是全文搜索相对于顺序扫描的优势之一:一次索引,多次使用

    以上就是本篇的内容,通过今天的内容我们了解了'搜索引擎'到底做了什么、它和普通的数据库搜索有什么区别、什么情况下才需要使用'搜索引擎'。


下期预告

    下一篇我们将深入拆解'搜索'引擎如何创建索引?

    为什么在输入了错别字的情况下,百度依然返回了正确的搜索结果? 


正文到此结束
本文目录