lucene如何索引文件?

时间:2010-04-08 17:51:25

标签: algorithm indexing lucene

我读了一些关于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树算法或任何其他算法进行索引 - 或者它有特定的算法吗?

4 个答案:

答案 0 :(得分: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/

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

答案 1 :(得分:27)

简而言之,Lucene使用磁盘上的Skip-Lists 构建反向索引,然后使用{{{}加载索引条件到内存的映射3}}(FST)。但是请注意Lucene Finite State Transducer,正如Lucene索引系统本身的作者Michael McCandless所描述的那样。请注意,通过使用Skip-Lists,索引可以从一个匹配遍历到另一个,使 set ,特别是范围查询成为可能(很像B-Trees) )。 does not (necessarily) load all indexed terms to RAM也解释了为什么Lucene的Skip-List实现被称为多级 Skip-List - 实质上是为了使O(log n)查找成为可能(再次,非常像B-树)。

因此,一旦基于Wikipedia entry on indexing Skip-Lists的反转(术语)索引是从文档构建的,索引就存储在磁盘上。 Lucene然后在Skip-List data structure的FST实现Finite State Transducer中加载(如已经说过:可能只有部分)这些术语到loosely inspired

Michael McCandless(也)做了Morfologick的一个非常好的和简洁的工作来将Lucene存储在内存中的术语编入索引,基本上是SortedMap<ByteSequence,SomeOutput>,并给出了FST如何工作的基本概念(即,FST如何压缩字节序列[即索引术语]以使该映射的内存使用增长为亚线性)。他指出explaining how and why Lucene uses a (minimal acyclic) FST Lucene也使用了。

对于那些好奇为什么Lucene使用Skip-Lists,而大多数数据库使用(B +) - 和/或(B)-Trees,请看the paper that describes the particular FST algorithm关于这个问题(Skip-Lists vs. B-树)。这个答案提供了一个非常好的,深刻的解释 - 基本上,这么多使得索引的并发更新“更容易”(因为你可以决定不立即重新平衡B树,从而获得关于与Skip-List相同的并发性能),而是 Skip-Lists使您不必处理(延迟或不延迟)平衡操作(最终) B-Trees需要的(事实上,正如答案显示/引用,如果两者都“完成正确”,B树和[多级] Skip-Lists之间的性能差异可能非常小。)

答案 2 :(得分:21)

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

如果忽略底层细节,索引过程非常简单。 Lucene形成了所谓的&#34;倒排索引&#34;来自文件。因此,如果文档带有文本&#34;要成为或不成为&#34;并且id = 1进来,倒排索引看起来像:

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

这基本上是 - 包含给定单词的文档中从单词到列表的索引。该索引(单词)的每一行称为发布列表。这个指数在长期存储中持续存在。

实际上事情当然更复杂:

  • Lucene可能会根据给定的特定分析器跳过一些单词;
  • 可以使用词干算法对单词进行预处理以减少语言的弹性;
  • 发布列表不仅可以包含文档的标识符,还可以包含文档中给定单词的偏移量(可能是多个实例)和其他一些附加信息。

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

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

所以出现了问题 - 我们如何更改已编入索引的文档

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

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

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

希望它有所帮助。

答案 3 :(得分:12)

它是inverted index,但没有指定它使用的结构。 Index format in lucene有完整的信息 从“文件扩展名摘要”开始。

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