Lucene的算法

Posted

技术标签:

【中文标题】Lucene的算法【英文标题】:Lucene's algorithm 【发布时间】:2012-05-06 15:11:03 【问题描述】:

我读了 Doug Cutting 的论文; “Space optimizations for total ranking”。

由于是很久以前写的,不知道lucene用的是什么算法(关于帖子列表遍历和分数计算,排名)。

特别是,那里描述的总排名算法涉及遍历每个查询词的整个帖子列表,因此在非常常见的查询词(如“yellow dog”)的情况下,这两个词中的任何一个都可能有一个非常长的帖子列表在网络搜索的情况下。它们真的都在当前的 Lucene/Solr 中遍历了吗?或者是否有任何启发式方法来截断使用的列表?

在只返回前k个结果的情况下,我可以理解将发布列表分布在多台机器上,然后将每台机器的前k个组合起来是可行的,但是如果我们需要返回“第100个结果” page”,即排名从第990--1000的结果,那么每个分区仍然要找出前1000,所以 分区不会有太大帮助。

总的来说,是否有关于 Lucene 使用的内部算法的最新详细文档?

【问题讨论】:

此外,任何人都大致知道(当然细节是秘密,但我想这些天主要思想应该足够普遍)谷歌如何在使用 AND 的多词查询的情况下快速排名? (如果他们的帖子是按PageRank顺序排序的,那么单个term查询很快就会返回top-k是可以理解的,但是如果是multi-term,他们就必须遍历整个列表才能找到插入集,因为列表不按 docId 排序,如 Lucene 纸质案例) 我不知道这实际上是如何工作的,但是如果您想提前终止查询,您应该使索引顺序(doc ids)匹配相关性(在您的情况下为 pagerank)顺序,至少在每个细分市场的基础。这将解决您的多词查询问题。 【参考方案1】:

我不知道此类文档,但由于 Lucene 是开源的,我鼓励您阅读源代码。特别是当前的trunk版本包含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 Jeff Dean 找到了这个 presentation,它解释了 Google 如何构建其大规模信息检索系统。特别是,它谈到了分片策略和发布列表编码。

【讨论】:

非常感谢您的回答,我会尝试挖掘 Twitter 链接,看看是否可以找到更多参考资料 如果遍历整个帖子列表,这似乎表明 Lucene 对于网络规模的搜索并不可行,因为像“黄狗”这样的东西必然会匹配世界上数十亿个网页.即使在积极分区之后,遍历每个盒子上的帖子的时间也会太长 @user933882 嗯,它可能需要一些调整,但 Twitter 示例表明 Lucene 可用于处理大量快速变化的数据。 非常感谢您的参考,他们很有帮助

以上是关于Lucene的算法的主要内容,如果未能解决你的问题,请参考以下文章

lucene实战--打分算法没有那么难?

lucene实战--打分算法没有那么难?

Elasticseach的评分机制

lucene相关

解剖 Lucene 的总体架构

Lucene的数值索引以及范围查询