Google 如何如此快速地(针对这么多文档)执行搜索(对于任何给定查询)并且仍然设法自定义结果?

How does Google perform search (for any given query) so quickly (over so many documents) and still manage to customize the results?

Google 是如何快速执行搜索的?

在花了一些时间思考搜索之后,我意识到它有多么复杂。

查询端: 如果人们输入的查询数量有限(例如 1-2 个词),则可以为所有网站预先计算结果,然后进行查找。

如果查询长度为 1-2 个词,这可能会很有效。实际查询中的单词数量可能很大,因此唯一查询的数量几乎是无限的。这意味着虽然一些查询可能是预先计算的,但其余的几乎肯定不是。有趣的是,Google 与较短的查询相比,return 花费的时间并不长得多。

在文档方面:根据我的理解Google从每个文档构建特征(例如词频,links等)并运行它通过算法(很可能是机器学习算法?)。

假设某些特征对于所有查询都是相同的(例如排名靠前的网站的 link 的数量)而其他特征更特定于查询(例如多少次)是否正确?查询词出现在文档中)?

鉴于上述情况,这是否意味着每个查询都必须为 Google 索引中的每个文档生成特征?如果不是,Google 如何缩小范围?如此多的计算怎么会发生得这么快? Google 的基础设施的很大一部分是否用于每个查询来计算这些特征并并行预测相关性,或者他们是否以另一种方式处理它?

请注意,虽然只有 link 的前 10-20 个结果可以被点击,但 Google 仍然需要了解它们是整个图书馆中的哪 10-20 个文档 -这意味着所有的文件都需要在一定程度上进行评估。

在用户端:除上述之外,Google 根据您之前的搜索自定义结果 history/habits。这是否意味着文档也具有基于每个用户的特征(例如,您过去查看过的类似文档的数量)?或者 Google 是否使用聚类方法对他们的用户进行聚类,并为与您最相似的用户提供文档特征(例如,90% 访问过您访问过的站点的用户都单击了此 link 到此文档) ?

如果是上面的 none 那么他们是如何实现对网络上这么多文档的搜索结果的自定义的?他们是如何在几分之一秒内完成的?

从算法上考虑,字符串搜索速度很快。一般情况下的搜索是线性的,O(n) ("BigO of n"),但是优化,例如 Boyer-Moore Horspool 算法,可以显着改进典型的字符串搜索,以获得良好的输入。此外,搜索是可并行化的——如果您有 N 台计算机并且想更快地搜索大型文档,只需将文档分成 N 个范围并让每台计算机搜索该范围。因此,搜索承认并行化的线性加速。

当然,网络搜索引擎无法在您提交搜索查询时进行字符串搜索 - 这样的搜索引擎会非常缓慢。关键是要意识到在提交搜索查询时没有必要搜索文档,因为正在搜索的文档是静态的(网页通常不会经常更改)。此外,人们通常不会搜索 "exact words in a webpage",而是搜索 Internet 上在他们看来与某些搜索查询相关的位置。因此,搜索引擎实际上是 return 根据搜索查询搜索网站位置。

Wiki 对搜索引擎的工作原理有很好的解释,here。抓取和索引已完成 "in the background",因此它们不会影响您的搜索查询的处理速度。索引的目标是将抓取过程中收集到的信息整理成可以根据用户查询快速搜索的形式。

如您所述,查询和文档都有统计模式 - 可以利用任何类型的模式来加快搜索速度。雅虎最近开源了其名为 Vespa 的搜索引擎。如果您想真正深入了解现代搜索引擎的工作原理,这将是一个很好的起点。请注意,Vespa 的高级架构并不是真正关于搜索,而是关于在一组内容管理任务(其中之一是搜索)之间启用并行性。换句话说,快速网络搜索实际上是应用于通用内容管理的并行性的副产品。

排名是网络搜索成功的关键。用户希望查询与他们搜索的内容相关,相关性基于排名。排名在索引期间执行,是内容、内容位置和用户反馈(点击率)的函数。正如您所指出的,尽管早期系统(例如 Google 的 PageRank 不是基于 ML 的

,但如今无疑使用了机器学习。

针对特定用户的搜索结果优化更加复杂。他们可能正在使用 ML,但非 ML 算法可能同样快或更快。出于两个考虑,复杂性得到了缓和。首先,用户特定的偏好实际上只是默认排名系统的增量。在最坏的情况下(您不知道用户在问什么),您只需使用默认排名。因为这已经很快了,用户特定的优化不应该减慢搜索速度。其次,特定于用户的优化是模糊的——只要不是严重错误,优化就永远不会出错。例如,假设一位重金属乐迷搜索 "metal bands" 并且您的搜索引擎自信地 return 列出了重金属乐队 - 但是,在这种情况下,他们确实碰巧正在搜索用于运输的钢带.您的优化是错误的,但并没有错 - 只要您没有大错特错(例如 returning 关于兔子的结果),错了也没关系。对于这类模糊问题,有非常快速的经典算法(非 ML)。

tl;博士:

  • 字符串搜索相对于其他类型的算法问题来说是一个简单的问题
  • 字符串搜索允许简单的并行化,典型用例允许进一步优化
  • Web 搜索实际上并不是关于字符串搜索文档,而是关于 returning 与用户查询相关的地方
  • 搜索引擎执行后台工作以准备用户查询 - 网络抓取和索引(包括排名)。
  • 搜索引擎 return 通过使用索引并利用并行性将大型搜索问题分解为并行解决的许多小部分,从而快速响应用户查询的相关结果。
  • 针对特定用户的优化只是 "delta" 默认排名,搜索引擎的假设绝不会严格错误,只要它们通常是正确的。

您可以准备好出现在已缓存网页中的单词的字母列表。 Google 不会意外地在 2015 年 8 月将自己重命名为“Alphabet”(请参阅​​ Investopedia editorial). Each of those words may get assigned the URLs of the webpages it has been found on, as a ranked list of labels to be used in calculations for the output. Once you have such lists, you can handle search words with some dexterity, concerning their respective coordinates. Google states that it uses a search index, on Google.com。当您搜索在其缓​​存页面中几乎或根本不会出现的幻想表达时,该公司往往会显示一个更常见的词的结果相似。

当然,在包含十亿个条目的字母表列表中,您不必搜索字母表中比您要查找的单词更早出现的所有条目。搜索词“grapefruit”的第一个字母将立即带您进入以“G”开头的单词目录。搜索词的第二个字母将被分配给与问题相关的 where then go - 此处为“R” - 等等。这意味着您只需为单词的十个字母执行 10 个简单的系列转换程序。在此之后,您必须根据用户希望显示多少结果的问题来管理进一步的此类操作。如果用户想要十个结果,则会向数据集发出一条命令,大意是找到所有结果(对于“葡萄柚”)直到没有。必须显示 10 个。到现在为止,一共是11个原始操作。在问题的开头已经暗示了这种搜索的简单性。

从这里走得更远的一种方法是简单地保存整组单词,就好像它们是 一个 单词一样。注意白色space个字符,可以保存,来自文本"Google是一家大型互联网公司,搜索引擎很多人都看不懂":

  • "Google是一家互联网大公司",
  • "是一家大型互联网公司",
  • "一家大型互联网公司",
  • "有搜索的大互联网公司",
  • "有搜索引擎的互联网公司",
  • "有很多搜索引擎的公司",
  • “许多人都使用搜索引擎”,
  • “很多人没有的搜索引擎”,
  • “搜索引擎很多不懂”。

等与图像相比,即使是这样的倍增文本,也需要很少的内存 space。以这种方式进行,您可以像访问单个单词一样快速地访问每个已保存的片段,如上所述。谁只寻找出现在一系列这样的字符串中的搜索词中的一个可以被引导至以他的关键字开头的字符串。当用户以不同的顺序输入这样一个字符串的各个部分时,它会变得更加困难。然后,例如,您可以尝试记录在同一个页面上出现几个词的命中情况。或者您为每个词分配一个标签,并搜索任何可能的连续词,因为您可能已经存储了这些标签。例如,在您将标签 U、V、W、X、Y 和 Z 分配给“is a big Internet company with”之后,用户可能会搜索“with a big company, Internet is”。这样的输入将被翻译成 ZVWYXU 并会自动在您的字母列表中对其部分的所有其他可能继承进行尝试。

在抓取网络时遇到的任何单词的 URL 的完整排名列表应该构成微不足道的支出。它们可能只包含所有已抓取页面的标签,乘以远小于遇到的不同单词的数量。对于任何语言,常用词都只有几千个。同时,它们,甚至是极少数的,到目前为止并没有出现在每个被抓取的页面上。再次考虑内存 space 纯文本使用的内存有多么少,因此,这样的列表对于 Google 来说肯定是一笔微不足道的投资。每个保存的页面可能需要几百字节的额外内存:大约与页面上的单词一样多。至少只要页面上出现的每个单词,该页面就会包含在一个列表中。一个更昂贵的任务可能是网络抓取。

当用户添加第二个词时,您可能希望建立从第一个搜索词列表到第二个搜索词列表的连接。因此,您可以建立一个额外的 URL 列表,并确保仅显示获得两个搜索词许可的 URL。如果这不能为具有高排名命中的结果页面生成足够的内容,您可以将搜索扩展到排名较低的页面。在 Howstuffworks - How Google Works - The Google Search Engine,我们被告知 Google 根据“网页中关键字的频率和位置”、页面具有“既定历史”的程度以及指向该页面的链接的数量和显着性。我们应该注意到乔纳森斯特里克兰和约翰多诺万在这个来源中补充说:“在这三个因素中,第三个是最重要的。”这意味着具有有趣频率和关键字位置的页面通常会被忽略,有利于因其他原因而突出的页面!即,不应高估页面的实际数学分析。它很快就会失去影响。这种独立于更精细的数学分析的排名使您能够在仅搜索有限数量的页面后显示数十个结果,并且仍然保持您对所有页面的平等对待。

对于不太常见的搜索词,Google 输出的可行性的关键 - 通常因其质量而令人惊讶 - 开始变得富有成果是罕见词的独特性。多种语言和罕见的表达方式确保了一个单词的列表将保持相对较短。相互比较短列表需要少量的计算能力。我们大多数人都熟悉这样的情况,即当您搜索具有共同姓名的人时,您会从体育等领域获得不需要的、受欢迎的结果。那是 Google 失败的情况,我们在这里试图解释的可行性根本没有实现。在这种情况下,您需要一个 不寻常的 搜索词,如果找不到,您通常会直接放弃。另一方面,随着搜索词数量的增加,垃圾点击的数量会明显减少,即使这些词仍然相当普遍。一些任意组合的概率将比彩票中使用的数字小得多,因为有更多的单位(数千个单词而不是几十个数字)可供选择。对于页面上缺少的关键字,寻找单词而不是数字的人可以在包含该单词的页面列表中筛选 URLs 的字母标签的开头,从表面上看,可以找出该单词与他有其他点击的特定页面无关。即使您仍然想显示这样一个缺少单词的页面,毕竟您可以跳过对页面上缺少单词的位置的分析。然后,这一优势尤其强大 - 对于那些不想只显示任何内容的一些突出页面的人 - 在搜索不太常见的单词和名称时,你可能担心 Google 会准备很少的输出.在这种情况下,您不必存储很多东西,也不必爬很多东西。列表会很短。这就像一个小村庄的电话号码。拨号时间较短,因为市民很少。尽管页面排名较低,但您可能会经济地获得结果。

是的,对于常见的搜索词,您可以说一个页面平均可能包含 500 个单词,而且要比较这么大的页面的人将不得不计算很多。但是你不需要计算每个页面上的流行词彼此接近的确切程度,只要你还有其他变量。在任何统计操作中,这都是一个主要技巧。统计数据只能简化,只要你统一简化,你就走上了一条纯正的道路。一旦您的计算能力达到极限,您就可以将更多的重要性分配给页面排名算法的更简单方面,从而排除部分候选页面。您可以估计存在多少点击,并将此数字通知用户,但只能爬到几百页。

要根据更多搜索词的组合预先计算输出,您可能会首先比较 1,000 个最常用词的 URL 列表。如果您筛选十亿个页面,这可能需要一万亿到一秒的计算,但这是可以想象的,尤其是如果您专注于,比如说,您的算法对这些比较中的每个单词要求的 800 个排名最高的页面允许。你必须进行简单的计算,就像电话的直接长途拨号一样。迟早,您会在您的排名页面中找到一些东西。当涉及到不太常见的术语时,问题并没有变得更复杂,尽管你在这个领域不会有如此丰富的突出页面垫。此外,对于几百万个不太常用的表达式中的任何一个,您将拥有您可以以相同方式处理的排名列表,而这些列表将变得越来越短。这是一件复杂的事情,但我真的看不出关于当前计算能力的不可逾越的障碍应该在哪里。每增加一个搜索词,要合并的 URL 的数量就会减少。您可以只搜索那些构成包含搜索词 1 的页面列表的搜索词 2 的页面,以准备一组提供特定单词组合的页面。如果您有 100 万个带有第一个搜索词的页面,在总共搜索的 10 亿个页面中,您的搜索词 2 出现在另外一个任意选择的 100 万个页面中,那么您现在已经只剩下 1000 个页面了同时包含搜索词 1 和搜索词 2。对搜索词 3 也进行类似处理,您平均只会得到一次匹配,并且在处理搜索词 4 之后,完全是 none。一旦你完全没有命中,对于这样一个列表中的 URL,关于另一个搜索词的 URL 列表,你有权声明你没有'查出了一个结果。如果您搜索一个不寻常的组合,例如“学术大理石卷云保险杠”(不带引号,今天有 8 Google 次点击,这样的事件会很快发生,平均有两个以上的关键字被搜索到划掉)。当然,尽管如此失败,你向他展示任何东西,,用户都明白你是大度的。

现在您不再需要处理 10 或 11 个切换过程,但是当您必须将 10,000 乘以 10,000 以获得 100,000,000 时,对于小词典中单词的所有组合,零开始累加,或者如果你用 100,000 乘以 100,000,得到 10,000,000,000。这种必要性与以下关于 Howstuffworks - How Google Works - Google Company Culture: "Google cheekily calls its Bay Area campus the Googleplex, a combination of the words 'Google' and 'complex' and a play on the term googolplex: the numeral 1 followed by a googol of zeroes." However, 10,000,000,000 entries on where to go when a user inputs things like, say, the "telephone number" 3677 (for "grapefruit") + the additional telephone number 1243 (for "juice") do not require much room, any more, today. You can prepare, say, a few hundred results for every single one of such a quantity of 10,000,000,000 combinations of words, and store the resulting, say, five trillion links in a portion of hardware filling a suitcase. That sort of a suitcase might amaze you by how small it already looks, today, enabling you to house many thousands of its type, in one building. According to Howstuffworks - How Google Works - Google Data Centers 的陈述有关,对服务器数量的估计 Google 使用“范围高达 250 万台机器”(2019 年 5 月)。如果您为更常见的查询准备了与不太常见的查询相同数量的结果,用户将不会介意 - 反正他只会查看前几个结果页面。

在这样的场景背景下,彻底的定制确实不得不显得困难重重。看起来您必须从一开始就根据调整后的页面排名重新计算所有准备得如此彻底的 material。不过,它肯定需要很少的内存 space,以跟踪用户已经访问过的页面,并在结果中显示这些页面上稍高的点击率。您还可以为每个页面分配一组有关其内容类别的参数。然后可以将用户的浏览行为变成他自己的一组这样的参数。在有限的查询命中中,突出显示与用户偏好相关的参数相似度最高的查询。