加入收藏 | 设为首页 | 会员中心 | 我要投稿 西安站长网 (https://www.029zz.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

“搜索”的原理,架构,实现,实践,面试不用再怕了(值得收藏)!!!

发布时间:2019-04-01 22:24:09 所属栏目:建站 来源:58沈剑
导读:副标题#e# 可能99%的同学不做搜索引擎,但99%的同学一定实现过检索功能。搜索,检索,这里面到底包含哪些技术的东西,希望本文能够给大家一些启示。 全网搜索引擎架构与流程如何? 全网搜索引擎的宏观架构如上图,核心子系统主要分为三部分(粉色部分): (1)s

分词后倒排索引:

  1. 我 -> {url1, url2} 
  2. 爱 -> {url1, url2} 
  3. 北京 -> {url1} 
  4. 到家 -> {url2, url3} 
  5. 美好 -> {url3} 

由检索词item快速找到包含这个查询词的网页Map>就是倒排索引。

画外音:明白了吧,词到url的过程,是倒排索引。

正排索引和倒排索引是spider和build_index系统提前建立好的数据结构,为什么要使用这两种数据结构,是因为它能够快速的实现“用户网页检索”需求。

画外音,业务需求决定架构实现,查询起来都很快。

检索的过程是什么样的?

假设搜索词是“我爱”:

  • 分词,“我爱”会分词为{我,爱},时间复杂度为O(1);
  • 每个分词后的item,从倒排索引查询包含这个item的网页list,时间复杂度也是O(1):
  • 求list的交集,就是符合所有查询词的结果网页,对于这个例子,{url1, url2}就是最终的查询结果;
    1. 我 -> {url1, url2} 
    2. 爱 -> {url1, url2} 

画外音:检索的过程也很简单:分词,查倒排索引,求结果集交集。

就结束了吗?其实不然,分词和倒排查询时间复杂度都是O(1),整个搜索的时间复杂度取决于“求list的交集”,问题转化为了求两个集合交集。

字符型的url不利于存储与计算,一般来说每个url会有一个数值型的url_id来标识,后文为了方便描述,list统一用list替代。

list1和list2,求交集怎么求?

(1) 方案一:for * for,土办法,时间复杂度O(n*n)

每个搜索词命中的网页是很多的,O(n*n)的复杂度是明显不能接受的。倒排索引是在创建之初可以进行排序预处理,问题转化成两个有序的list求交集,就方便多了。

画外音:比较笨的方法。

(2) 方案二:有序list求交集,拉链法

  1. 有序集合1{1,3,5,7,8,9} 
  2. 有序集合2{2,3,4,5,6,7} 

两个指针指向首元素,比较元素的大小:

  • 如果相同,放入结果集,随意移动一个指针;
  • 否则,移动值较小的一个指针,直到队尾;

这种方法的好处是:

  • 集合中的元素最多被比较一次,时间复杂度为O(n);
  • 多个有序集合可以同时进行,这适用于多个分词的item求url_id交集;

这个方法就像一条拉链的两边齿轮,一一比对就像拉链,故称为拉链法;

画外音:倒排索引是提前初始化的,可以利用“有序”这个特性。

(3) 方案三:分桶并行优化

数据量大时,url_id分桶水平切分+并行运算是一种常见的优化方法,如果能将list1和list2分成若干个桶区间,每个区间利用多线程并行求交集,各个线程结果集的并集,作为最终的结果集,能够大大的减少执行时间。

举例:

  1. 有序集合1{1,3,5,7,8,9, 10,30,50,70,80,90} 
  2. 有序集合2{2,3,4,5,6,7, 20,30,40,50,60,70} 

求交集,先进行分桶拆分:

  1. 桶1的范围为[1, 9] 
  2. 桶2的范围为[10, 100] 
  3. 桶3的范围为[101, max_int] 

于是:

集合1就拆分成

  1. 集合a{1,3,5,7,8,9} 
  2. 集合b{10,30,50,70,80,90} 
  3. 集合c{} 

集合2就拆分成

  1. 集合d{2,3,4,5,6,7} 
  2. 集合e{20,30,40,50,60,70} 
  3. 集合e{} 

(编辑:西安站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读