lucene 怎么这么快计算文档的交集?

Posted

技术标签:

【中文标题】lucene 怎么这么快计算文档的交集?【英文标题】:how does lucene calculate intersection of documents so fast? 【发布时间】:2011-12-03 09:08:03 【问题描述】:

允许这样做的存储和搜索的内部结构是什么?就像在细节中一样?

例如,我有一百万个文档与一个词匹配,还有一百万个文档与 AND 查询的第二个词匹配。 lucene怎么这么快就给我top k了?

它是否按每个术语的文档 IDS 递增的顺序存储文档?然后,当两个术语的文档必须相交时,它会在这两个集合中查找第一个公共的 k 个文档,方法是在一次遍历中递增地迭代它们。

或者,它是否使用较大文档数组中的简单无序散列集来查找公共文档?

或者是否根据用户询问的文档数量、由单个术语匹配的文档等以及其他因素来使用这两种(或可能更多)类型的交叉策略?

任何能指出文档数组合并细节的文章将不胜感激。

编辑: 感谢您的信息。现在说得通了。跳过列表很神奇。我会更深入地研究它以获得清晰的理解。

【问题讨论】:

Lucene 使用文档编号,而不是完整的文档本身,因此任何方法都可以。我敢打赌,每个术语都会使用有序的文档编号,但如果您真的对所有细节感兴趣,那么值得看看源代码。 很好的问题和答案。考虑到有多少人使用 Lucene/Solr 进行全文和其他非文本字段搜索,我对这里积累的选票如此之少感到惊讶。 【参考方案1】:
    索引包含已排序的文档。当您使用 and operator(term1 AND term2) 查询时,它使用两个迭代器,因此当您知道第一个 term1 以 docN 开头时,您可以跳过 term2 的所有文档直到 docN。因此不仅有带有 next 方法的迭代器,而且还有非常高效的 skipTo 方法。它是通过跳过列表索引(http://en.wikipedia.org/wiki/Skip_list)实现的。 因此,通过使用 next 和 skipTo 方法,我们可以非常快速地迭代大块,并且由于数据稀疏(例如,这些数据不适用于通常的数据库)它非常有效。 Lucene 仅保存 N 最好的其他点,因此它比对所有分数文档进行排序要快得多。如果您请求 10 个最佳文件,则速度比您请求 20 个最佳文件快两倍

【讨论】:

第 1 点是有道理的。但我对第 2 点表示怀疑。Xodarap 分享的帖子的说法不同。我需要深入研究 我在阅读 lucene 源代码和编写我自己的查询实现期间获得了这些信息。如果您想重复我的路径,我建议您阅读 BooleanScorer src(如 Coady 所说)和相关课程。 @GuySensei:yura 是非常正确的——如果 Lucene 知道一个文档不会在前 N 个中,它会通过一些聪明的修剪算法被忽略。所以并不完全是它只包含前 N 个,但它不是一个糟糕的简化。 (请注意,这种修剪的用处取决于您的查询 - 有时 Lucene 只需要查看所有内容。)【参考方案2】:

Lucene 将根据情况与已排序的文档 ID 相交或使用位集窗口。查看BooleanScorer顶部的cmets。

【讨论】:

【参考方案3】:

Intersection 类似于sort-merge join,除了 ID 已经排序。请参阅this blog post 了解更多信息。

【讨论】:

以上是关于lucene 怎么这么快计算文档的交集?的主要内容,如果未能解决你的问题,请参考以下文章

集群文档 Lucene

有这么一项技术,据说可能取代云计算,你怎么看?

详解 Lucene 对 Term的权重(Term weight) 计算

《从Lucene到Elasticsearch:全文检索实战》学习笔记五

Lucene in action 笔记 term vector——针对特定field建立的词频向量空间,用cos计算针对该field的文档相似度

Lucene的评分(score)机制研究