基本原理
百度百科上有简单的介绍,但实际商业化的搜索引擎要比这复杂得多,就像原子弹爆炸的理论大家都知道,但真正能造出原子弹的公司也屈指可数。
在线主要流程
语义理解
如何理解用户的搜索 query,比如用户搜索,query = 北京天气怎么样,我们如何理解到用户的意图是要查询北京的天气
这其中可能还包括query的改写和纠错,比如用户输入 query = 刘得华,我们是否可以认为用户是想搜索 query = 刘德华,我们如何判断两个词的相似度或者关联性,这其中可能会用到编辑距离的知识,也可以应用机器学习或者人工干预标注的手段
召回
确认哪些结果可以被召回,还是以query = 北京天气 举例,我们如何理解这个词,是将“北京天气”作为一个整体去理解,还是将“北京”、“天气”作为不同的整体去理解,甚至是理解成“北”、“京”、“天”、“气”这四个词,英文的分词在某些方面,其实会比中文要容易一些,因为英文每个单词中间是有空格去隔开的,但语言的二义性在很多语言中都是存在的,比如 query = Apple,用户的意图是想去寻找苹果公司的官网呢,还是苹果本身呢,两个类型的结果都召回的话,我们在排序方面,还需要考虑相关的权重的问题。
排序
一般会分为粗排和精排,一般粗排的结果会比较多,数据还可能来自不同的来源,粗排一般比较粗糙地计算相关性,计算的维度较少,或者是根本不计算,在精排的时候,再从多个维度去计算相关性,并且排序本身也还会受用户点击等行为的影响。
模块划分
其实主要也就分为三个模块:
信息采集
一般这一步就是我们所熟知的爬虫的工作过程,如何爬取互联网上所有的信息,这其实也是一个很复杂的事情,其复杂度主要在以下几个方面:
互联网全量数据抓取
互联网的网页这么多,每天还在不停地新增,我们如何去遍历这些网页,这个其实可以抽象成图论的遍历 网站如果本身希望有更好地抓取方式,搜索公司也给出了自己的解决方案,用户希望爬虫如何抓取自己的网页,可以按照搜索公司给的格式自行定义海量数据如何存储
其实这块就涉及到了google的三驾马车中的GFS和BigTable如何判定网页已经抓取过
这块我想到的方案其实布隆过滤器,比较低成本地去做这个事情,但还是要用分布式存储去存网页本身的hash,作为兜底的查询。如何确定每个网站的更新频率问题
不同网站的更新时效如何确定,这个各家的策略应该都不太一样。比如股票、天气等高时效要求的内容,与一般的博客那种低失效内容,其抓取频率肯定是有diff的。这个应该与网站的权重、更新频次、内容类型等多方面因素有关。
离线建库
爬虫抓取到的信息,大多数是非结构化的,如何将这非结构化的数据转换为结构化的信息,因为最终搜索呈现给用户的,肯定是结构化的数据,并且本身我们要做各种粗排+精排的话,也是需要结构化的数据才能一起排。
离线建库本身又会获取很多内容信息,作为在线检索排序的依据,比如网站的权重会影响在线检索的排序,而在线检索本身
在线检索
对用户搜索的 query 进行语义识别,改写、纠错、切词
ES中关于改写
商业搜索引擎的技术难点
- 内容理解,非结构化数据转为结构化数据
- 离线建库过程的可观测性
- 相关性计算
- 存储引擎如何在性能与成本的衡量