我读了一些关于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树算法或任何其他算法进行索引 - 或者它有特定的算法吗?
答案 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使用索引完成所有服务操作并关闭它,因此可以进行搜索。提交索引后基本上是不可变的。此索引(或索引部分)称为 segment 。当Lucene执行搜索查询时,它会搜索所有可用的段。
所以出现了问题 - 我们如何更改已编入索引的文档?
新索引文档的新文档或新版本将在新细分中编制索引,旧版本在之前的细分中使用所谓的 kill list 无效。杀戮列表是可以更改的已提交索引的唯一部分。正如您可能猜到的,索引效率会随着时间的推移而下降,因为旧索引可能包含大部分已删除的文档。
这就是合并的地方。合并 - 是将多个索引组合在一起以提高整体效率的过程。在合并期间基本上发生的是复制到新段的实时文档和完全删除旧段。
使用这个简单的过程,Lucene能够在搜索性能方面保持良好的索引。
希望它有所帮助。
答案 3 :(得分:12)
它是inverted index,但没有指定它使用的结构。 Index format in lucene有完整的信息 从“文件扩展名摘要”开始。
您首先会注意到它会讨论各种不同的索引。 据我所知,这些都没有严格使用B-tree,但有相似之处 - 上述结构确实类似于树。