我读过Doug Cutting的论文; “Space optimizations for total ranking”。
由于它是很久以前编写的,我想知道lucene使用的算法(关于帖子列表遍历和分数计算,排名)。
特别是,那里描述的总排名算法涉及遍历每个查询词的整个帖子列表,因此如果是非常常见的查询词,如“黄狗”,则2个词中的任何一个可能具有非常长的帖子列表在网络搜索的情况下。它们是否真的遍及当前的Lucene / Solr?或者是否有任何启发式方法来截断所使用的列表?
在只返回前k个结果的情况下,我可以理解在多个机器上分发帖子列表,然后组合每个机器的top-k可以工作,但是如果我们需要返回“第100个结果”页面“,即结果排名从990-1000,然后每个分区仍然必须找出前1000,所以 分区无济于事。
总的来说,是否有关于Lucene使用的内部算法的最新详细文档?
答案 0 :(得分:30)
我不知道这样的文档,但由于Lucene是开源的,我鼓励你去阅读源代码。特别是,当前的主干版本包括flexible indexing,这意味着存储和发布列表遍历已与其余代码分离,从而可以编写自定义编解码器。
关于发布列表遍历,您的假设是正确的(默认情况下(取决于您的Scorer实现)Lucene遍历查询中存在的每个术语的整个发布列表,并将匹配的文档放入大小为k的堆中计算top-k文档(参见TopDocsCollector)。因此,将结果从990返回到1000会使Lucene实例化一个大小为1000的堆。如果按文档对索引进行分区(另一种方法可能是按术语分割),则每个分片都需要将前1000个结果发送到服务器,即负责合并结果(例如,参见Solr QueryComponent,它将查询从N转换为P> N到几个从0到P sreq.params.set(CommonParams.START, "0");
的分片请求。这就是为什么在极端分页的情况下,Solr在分布式模式下可能比在独立模式下慢。
我不知道Google如何有效地对结果进行评分,但Twitter发布了一个paper on their retrieval engine Earlybird,他们解释了他们如何修补Lucene以便对帖子列表进行有效的反向时间顺序遍历,这使他们能够返回与查询匹配的最新推文,而不会遍历每个字词的整个发布列表。
<强>更新强> 我从Googler presentation找到了这个Jeff Dean,它解释了Google如何构建其大规模信息检索系统。特别是,它讨论了分片策略和发布列表编码。