首页 文章

lucene 如何索引文件?

提问于
浏览
85

我读了一些关于 Lucene 的文件;我也在这个链接(http://lucene.sourceforge.net/talks/pisa)中阅读了该文件。

我真的不明白 Lucene 如何索引文档并且不了解 Lucene 用于索引的算法?

在上面的链接中,它表示 Lucene 使用此算法进行索引:

  • 增量算法:
  • 维护一堆段索引

  • 为每个传入文档创建索引

  • 将新索引推入堆栈

  • 让 b=10 成为合并因子; M=8


for (size = 1; size < M; size *= b) {
    if (there are b indexes with size docs on top of the stack) {
        pop them off the stack;
        merge them into a single index;
        push the merged index onto the stack;
    } else {
        break;
    }
}

该算法如何提供优化的索引?

Lucene 是否使用 B-tree 算法或任何其他算法进行索引 - 或者它是否具有特定算法?

4 回答

  • 53

    这里有一篇相当不错的文章:https://web.archive.org/web/20130904073403/http://www.ibm.com/developerworks/library/wa-lucene/

    编辑 12/2014:由于原始文件被删除,已更新为已存档版本,可能最近的替代方案是http://lucene.apache.org/core/3_6_2/fileformats.html

    http://lucene.apache.org/core/4_10_2/core/org/apache/lucene/codecs/lucene410/package-summary.html#package_description有一个更新的版本,但它似乎比旧版本的信息少。

    简而言之,当 lucene 索引文档时,它会将其分解为多个术语。然后,它将这些术语存储在索引文件中,其中每个术语与包含它的文档相关联。您可以将其视为有点像哈希表。

    使用分析器生成术语,该分析器将每个单词的词根形成为根。最流行的英语词干算法是 Porter 词干算法:http://tartarus.org/~martin/PorterStemmer/

    发出查询时,它将通过用于构建索引的相同分析器进行处理,然后用于在索引中查找匹配的 term(s)。这提供了与查询匹配的文档列表。

  • 29

    简而言之,Lucene 使用磁盘上的Skip-Lists构建反向索引,然后使用有限状态传感器(FST)将索引术语的映射加载到内存中。然而,请注意 Lucene 不(必然)将所有索引术语加载到 RAM,正如 Lucene 的索引系统本身的作者 Michael McCandless 所描述的那样。请注意,通过使用 Skip-Lists,可以将索引从一个匹配遍历到另一个匹配,从而使得设置,特别是范围查询成为可能(非常类似于 B-Trees)。 关于索引的维基百科条目 Skip-Lists也解释了为什么 Lucene 的 Skip-List 实现被称为 multi-level Skip-List - 实质上是为了使O(log n) 成为可能(再次,非常像 B-Trees)。

    因此,一旦从文档构建了倒置(term)索引(基于Skip-List 数据结构),索引就会存储在磁盘上。然后 Lucene 将这些术语加载(如已经说过:可能只有一部分)到有限状态传感器,在 FST 实现中松散的灵感Morfologick加载。

    Michael McCandless(也)做了一个非常好的简洁的解释 Lucene 如何以及为何使用(最小非循环)FST工作来将 Lucene 存储在内存中的术语索引,基本上是SortedMap<ByteSequence,SomeOutput>,并给出了 FST 如何工作的基本思路(i.e.,FST 如何压缩字节序列[29] ]使内存使用此映射增长 sub-linear)。而且他指出描述特定 FST 算法的论文 Lucene 也使用了。

    对于那些好奇为什么 Lucene 使用 Skip-Lists,而大多数数据库使用(B) - and/or(B)-Trees,看看正确的答案关于这个问题(Skip-Lists vs. B-Trees)。这个答案提供了一个非常好的,深刻的解释 - 基本上,这么多使得索引的并发更新“更适合”(因为你可以决定不立即 re-balance B-Tree,从而获得与 Skip-List 相同的并发性能),而是 Skip-Lists 使你免于必须工作(延迟或不延迟)B-Trees 所需的平衡操作(最终)(事实上,作为答案 shows/references,B-Trees 和[34] Skip-Lists 之间的性能差异可能非常小,如果其中任何一个“做得对”.)

  • 22

    似乎你的问题更多的是关于索引合并而不是关于索引本身。

    如果忽略 low-level 详细信息,索引过程非常简单。 Lucene 从文档中形成所谓的“倒排索引”。因此,如果带有文本“要成为或不成为”且 id=1 的文档进入,则反向索引将如下所示:

    [to] → 1
    [be] → 1
    [or] → 1
    [not] → 1
    

    这基本上就是 - 从单词到包含给定单词的文档列表的索引。该索引(单词)的每一行称为发布列表。此索引将保留在 long-term storage 上。

    实际上事情当然更复杂:

    • Lucene 可能会根据给定的特定分析器跳过一些单词;

    • 可以使用词干算法对单词进行预处理,以减少语言的弹性;

    • 发布列表不仅可以包含文档的标识符,还可以包含文档内给定单词的偏移量(可能是几个实例)和一些其他附加信息。

    还有许多并发症对于基本理解而言并不那么重要。

    但重要的是要理解,Lucene 索引只是附加。在某些时间点,应用程序决定提交(发布)索引中的所有更改。 Lucene 用索引完成所有服务操作并关闭它,因此它可用于搜索。提交索引后基本上是不可变的。该索引(或索引部分)称为段。当 Lucene 执行搜索查询时,它会搜索所有可用的段。

    所以问题就出现了 - 我们怎样才能改变已编入索引的文件?

    新索引文档的新文档或新版本将在新段中编入索引,旧版本在之前的段中使用所谓的杀死列表无效。杀戮列表是可以更改的已提交索引的唯一部分。正如您可能猜到的,索引效率会随着时间的推移而下降,因为旧索引可能包含大部分已删除

    这就是合并的地方。合并 - 是将多个索引组合在一起以提高整体效率的过程。在合并期间基本上发生的是复制到新段的实时文档和完全删除的旧段。

    使用这个简单的过程,Lucene 能够在搜索性能方面保持良好的索引。

    希望它会有所帮助。

  • 12

    它是倒指数,但是没有指定它使用的结构。 lucene 中的索引格式有完整的信息。
    从“文件扩展名摘要”开始。

    你会首先注意到它涉及各种不同的索引。据我所知,这些都没有严格使用B-tree,但有相似之处 - 上述结构确实类似树木。

相关问题