我理解全文搜索的一个基本方面是使用inverted indexes。因此,使用反向索引,单字查询变得微不足道。假设索引的结构如下:
some-word - > [doc385,doc211,doc39977,...](按排名,降序排序)
要回答该单词的查询,解决方案就是在索引中找到正确的条目(需要O(log n)时间)并从指定的列表中显示一些给定数量的文档(例如前10个)索引。
但是那些返回与两个单词匹配的文档的查询呢?最直接的实现如下:
现在,第三步可能需要O(n log n)时间来执行。对于非常大的A和B,可能使查询缓慢回答。但像谷歌这样的搜索引擎总会在几毫秒内回复他们的答案。所以这不是完整的答案。
一个明显的优化是,由于像谷歌这样的搜索引擎无论如何都没有返回所有匹配的文档,我们不必计算整个交集。我们可以从最小的集合(例如B)开始,找到也属于另一集合的足够条目(例如A)。
但我们还不能有以下最糟糕的情况吗?如果我们将A设置为与公共单词匹配的文档集,并且集B是与另一个常用单词匹配的文档集,则可能仍然存在A∩B非常小的情况(即,该组合很少)。这意味着搜索引擎必须线性地遍历B的所有元素x成员,检查它们是否也是A的元素,以找到符合这两个条件的少数元素。
线性并不快。并且您可以使用两个以上的单词进行搜索,因此仅使用并行性肯定不是整个解决方案。那么,这些案例如何优化?大型全文搜索引擎是否使用某种复合索引?布隆过滤器?有什么想法吗?
答案 0 :(得分:6)
正如你所说某些词 - > [doc385,doc211,doc39977,...](按排名,降序排序),我认为搜索引擎可能不会这样做,文档列表应按文档ID排序,每个文档根据单词排名 查询到来时,它包含多个关键字。对于每个单词,您都可以找到一个文档列表。对于所有关键字,您可以执行合并操作,并计算doc与查询的相关性。最后将排名靠前的相关文档返回给用户 并且查询过程可以分发以获得更好的性能。
答案 1 :(得分:4)
大多数系统以某种方式以某种方式实现TF-IDF。 TF-IDF是函数项频率和逆文档频率的乘积。
IDF功能将文档频率与集合中的文档总数相关联。这个函数的共同直觉是,对于出现在少数文档中的术语,它应该给出更高的值,对于出现在所有文档中的术语,它们的值越低,使得它们无关紧要。
你提到谷歌,但谷歌使用PageRank(链接输入/输出)以及术语频率和接近度来优化搜索。 Google分发数据并使用Map / Reduce来并行化操作 - 计算PageRank + TF-IDF。
Information Retrieval: Implementing Search Engines第2章对此背后的理论有了很好的解释。进一步调查的另一个想法也是看Solr如何实现这一点。
答案 2 :(得分:3)
即使没有排名,我也想知道谷歌如何快速计算两组的交集。
显然,对于某些单词A,B,C计算交集的最坏情况是当它们的索引非常大并且交点非常小时。典型的情况是搜索不同语言中的一些非常常见的(在DB术语中“流行”)单词。
让我们试试中文的“具体”和位置(“网站”,“位置”)和日语中的极端な(“极端”)。
Google搜索位置返回“大约1,500,000,000条结果(0.28秒)” 谷歌搜索“具体”返回“约2,020,000,000结果(0.46秒)” Google搜索“极端な”约7,590,000条结果(0.25秒)
所有三个术语都出现在同一个文档中是极不可能的,但让我们谷歌吧: 谷歌搜索“具体位置极端な”返回“约174,000个结果(0.13秒)”
添加俄语单词“игра”(游戏) 搜索:约212,000,000个结果(0.37秒)
搜索所有这些:“играconcrete位置极端な”返回约12,600个结果(0.33秒)
当然,返回的搜索结果是无意义的,并且它们不包含所有搜索字词。
但是查看组合查询的查询时间,我想知道是否在单词索引上计算了一些交集。即使所有内容都在RAM中并且大量分片,计算两组与1,500,000,000和2,020,000,000个条目的交集也是O(n)并且几乎不能在<0.5秒内完成,因为数据在不同的机器上并且它们必须通信。
必须有一些连接计算,但至少对于流行的单词,这肯定不会在整个单词索引上完成。添加结果模糊的事实,似乎很明显谷歌使用了一些优化类型“回馈一些高排名的结果,并在0.5秒后停止”。
这是如何实现的,我不知道。有什么想法吗?
答案 3 :(得分:3)
Google无需实际查找所有结果,只需查看最高结果。 索引可以按年级排序,然后按ID排序。由于相同的ID总是具有相同的等级,因此不会损害设置交叉时间。
所以谷歌开始交叉直到它找到10个结果,然后做一个统计估计,告诉你它发现了多少结果。
最糟糕的情况几乎是不可能的。 如果所有单词都是&#34;常见的&#34;那么交集将非常快速地给出前10个结果。如果有一个罕见的词,那么交叉很快,因为复杂度是O(N long M),其中N是最小的群。
你需要记住谷歌在内存中保留它的索引并使用并行计算。例如,U可以将问题分成两个搜索,每个搜索只搜索一半的网络,然后确定结果并采取最佳措施。谷歌有数百万计算