lucene如何索引文件?


95

我读了一些有关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树算法或类似索引的任何其他算法-还是有特定的算法?


此处的大多数答案是正确的,因为第一个Lucene首先创建了倒排索引,但这并不能解释随后如何搜索术语索引的关键点(我相信,这是OP的实际要求)。因此,请在下面找到这个较旧的问题的新答案,希望可以提供更好的见解。
fnl

1
再次更新我的答案,因为当前的答案(包括我的!)不能令人满意地回答OP的两个主要问题(Lucene如何提供优化的索引编制以及采用哪种特定算法-跳过列表,而不是B树,顺便说一句)。希望我的最终更新现在能够正确回答实际问题!
fnl

Answers:


54

这里有一篇相当不错的文章: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/

发出查询时,将通过用于构建索引的同一分析器来处理该查询,然后使用该分析器在索引中查找匹配项。这提供了与查询匹配的文档列表。


感谢您的回答和链接。但是我听说Lucene项目有一个名为“ Snowball”的特殊词干吗?你有没有听说过?
Mehdi Amrollahi 2010年

这是一个不同的问题:请参阅lucidimagination.com/search/…除此之外,看到您的问题模式,我建议您阅读“ Lucene in Action”一书:manning.com/hatcher2(第一版有些陈旧,但是可以可以在枯树版本中找到。第二版可以作为电子书购买)。
Yuval F

5
您可以修改您的答案吗,找不到第一个链接是IBM链接:)
Adelin

此外,字段如何输入整个图片?如果在特定字段上进行查询,lucene如何以及在什么时候知道指向文档的术语不在文档中的任何位置,而是在请求的字段内?
列文·塔拉佐夫

44

简而言之,Lucene使用磁盘上的Skip-Lists 构建了一个反向索引,然后使用有限状态转换器(FST)将索引项的映射加载到内存中。但是请注意,Lucene 不会(必需)将所有索引项加载到RAM,正如Lucene的索引系统作者本人Michael McCandless所描述的那样。请注意,通过使用“跳过列表”,可以将索引从一个命中遍历到另一个命中,从而使诸如set(尤其是范围查询)之类的事情成为可能(非常类似于B-Trees)。而在索引跳跃-列出维基百科条目也解释了为什么Lucene的跳过-List实现被称为多级跳过列表-从本质上讲,使O(log n)查找成为可能(同样,非常类似于B树)。

因此,一旦从文档中构建了基于Skip-List数据结构的反向(项)索引,该索引就会存储在磁盘上。然后,在由Morfologick 启发的FST实现中,Lucene将这些术语(如已经说过的:可能只有其中的一部分)加载到有限状态转换器中。

Michael McCandless(也)做了出色而简洁的工作,解释了Lucene如何以及为什么使用(最小无环)FST来索引Lucene存储在内存中的术语,本质上是作为SortedMap<ByteSequence,SomeOutput>,并给出了FST的工作原理(即FST如何压缩字节序列(即索引项),以使使用此映射的内存增长为亚线性)。他还指出了描述 Lucene使用的特定FST算法的论文

对于那些好奇为什么Lucene使用跳过列表,而大多数数据库使用(B +)和/或(B)-树的人,请查看有关此问题正确的 SO答案(跳过列表与B-树)。这个答案给出了一个很好的,深刻的解释-本质上,并没有太多地使索引的并发更新“更容易适应”(因为您可以决定不立即重新平衡B-Tree,从而获得与B-Tree相同的并发性能。跳过列表),但是跳过列表使您不必进行(延迟的或不延迟的)平衡操作 (最终)B树需要(实际上,如答案所示/参考所示,如果两个B树和[多级]跳过列表之间的执行正确,那么它们之间的性能差异可能很小。)


1
Afaik他们使用跳过列表而不是B树来减少磁盘搜索次数,因为跳过列表的一部分驻留在内存中,并且遍历索引时几乎不需要磁盘IO
Anton

24

看来您的问题更多是关于索引合并,而不是索引本身。

如果您忽略低级详细信息,索引编制过程将非常简单。Lucene从文档中形成所谓的“倒排索引”。因此,如果输入文本为“ To be or not be be”且id = 1的文档,则倒排索引将如下所示:

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

基本上就是这样-从单词到包含给定单词的文档列表的索引。该索引(单词)的每一行称为发布列表。然后,该索引将保留在长期存储中。

实际上,事情当然更加复杂:

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

还有更多的并发症,对于基本的了解来说并不是那么重要。

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

因此出现了问题–我们如何才能更改已建立索引的文档

新文档或已建立索引文档的新版本在新段中建立索引,而旧版本在先前段中无效(使用所谓的kill list)。杀死列表是已提交索引中唯一可以更改的部分。您可能会猜到,索引效率会随着时间下降,因为旧索引可能包含大部分已删除的文档。

这就是合并的目的。合并–是合并多个索引以整体上提高索引效率的过程。合并期间基本上发生的是将活动文档复制到新段,并将旧段完全删除。

使用这种简单的过程,Lucene可以在搜索性能方面将索引保持良好的状态。

希望会有所帮助。


1
因此,为了首先找到最新结果,是从查找最新细分开始吗?因此,只需澄清一下-假设文档已更新。将文档的较旧版本添加到删除列表中,然后如果旧文档段中的文档ID与删除列表中的ID相匹配,则从搜索结果中删除在较旧段中找到的所有匹配项?
Joel B

2
是的,你是对的。唯一要提及的是,最终顺序是使用排序规则定义的(琐碎情况下的相关性索引),因此搜索段的顺序无关紧要。
Denis Bazhenov

12

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

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


1
Lucene的反向索引基于跳过列表,而不是B树。从广义上讲,它仍然是一个树状结构,但只是为了完整起见-例如,请参阅此SO问题。Lucene使用了跳过列表因此提出了一个问题,为什么跳过列表可能比B树更可取
fnl
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.