Skip to content

基本原理

百度百科上有简单的介绍,但实际商业化的搜索引擎要比这复杂得多,就像原子弹爆炸的理论大家都知道,但真正能造出原子弹的公司也屈指可数。

在线主要流程

语义理解

如何理解用户的搜索 query,比如用户搜索,query = 北京天气怎么样,我们如何理解到用户的意图是要查询北京的天气
这其中可能还包括query的改写和纠错,比如用户输入 query = 刘得华,我们是否可以认为用户是想搜索 query = 刘德华,我们如何判断两个词的相似度或者关联性,这其中可能会用到编辑距离的知识,也可以应用机器学习或者人工干预标注的手段

召回

确认哪些结果可以被召回,还是以query = 北京天气 举例,我们如何理解这个词,是将“北京天气”作为一个整体去理解,还是将“北京”、“天气”作为不同的整体去理解,甚至是理解成“北”、“京”、“天”、“气”这四个词,英文的分词在某些方面,其实会比中文要容易一些,因为英文每个单词中间是有空格去隔开的,但语言的二义性在很多语言中都是存在的,比如 query = Apple,用户的意图是想去寻找苹果公司的官网呢,还是苹果本身呢,两个类型的结果都召回的话,我们在排序方面,还需要考虑相关的权重的问题。

排序

一般会分为粗排和精排,一般粗排的结果会比较多,数据还可能来自不同的来源,粗排一般比较粗糙地计算相关性,计算的维度较少,或者是根本不计算,在精排的时候,再从多个维度去计算相关性,并且排序本身也还会受用户点击等行为的影响。

模块划分

其实主要也就分为三个模块:

信息采集

一般这一步就是我们所熟知的爬虫的工作过程,如何爬取互联网上所有的信息,这其实也是一个很复杂的事情,其复杂度主要在以下几个方面:

  1. 互联网全量数据抓取
    互联网的网页这么多,每天还在不停地新增,我们如何去遍历这些网页,这个其实可以抽象成图论的遍历 网站如果本身希望有更好地抓取方式,搜索公司也给出了自己的解决方案,用户希望爬虫如何抓取自己的网页,可以按照搜索公司给的格式自行定义

  2. 海量数据如何存储
    其实这块就涉及到了google的三驾马车中的GFS和BigTable

  3. 如何判定网页已经抓取过
    这块我想到的方案其实布隆过滤器,比较低成本地去做这个事情,但还是要用分布式存储去存网页本身的hash,作为兜底的查询。

  4. 如何确定每个网站的更新频率问题
    不同网站的更新时效如何确定,这个各家的策略应该都不太一样。比如股票、天气等高时效要求的内容,与一般的博客那种低失效内容,其抓取频率肯定是有diff的。这个应该与网站的权重、更新频次、内容类型等多方面因素有关。

离线建库

爬虫抓取到的信息,大多数是非结构化的,如何将这非结构化的数据转换为结构化的信息,因为最终搜索呈现给用户的,肯定是结构化的数据,并且本身我们要做各种粗排+精排的话,也是需要结构化的数据才能一起排。

离线建库本身又会获取很多内容信息,作为在线检索排序的依据,比如网站的权重会影响在线检索的排序,而在线检索本身

在线检索

对用户搜索的 query 进行语义识别,改写、纠错、切词
ES中关于改写

商业搜索引擎的技术难点

  1. 内容理解,非结构化数据转为结构化数据
  2. 离线建库过程的可观测性
  3. 相关性计算
  4. 存储引擎如何在性能与成本的衡量

参考文档

  1. https://yuerblog.cc/2018/01/09/elasticsearch-custom/
  2. 这就是搜索引擎
  3. https://res1.zcmu.edu.cn/vpn/2/https/www.mamioo.com/seojishu/section-4
  4. 自制搜索引擎