Lucene如何工作


90

我想了解Lucene搜索如何如此快速地工作。我在网络上找不到任何有用的文档。如果您有什么需要阅读(缺少Lucene源代码),请告诉我。

在我的情况下,使用带有索引的mysql5文本搜索的文本搜索查询大约需要18分钟。lucene搜索同一查询只需不到一秒钟的时间。


2
我可以要求将此问题转换为社区Wiki吗?Lucene现在听起来像一个平台。
2014年

Answers:


75

Lucene是反向全文索引。这意味着它将获取所有文档,将它们拆分为单词,然后为每个单词建立一个索引。由于索引是完全无序的字符串匹配,因此它可以非常快。假设,SQL上的无序索引varchar字段可能同样快,实际上,我认为您会发现在这种情况下,大型数据库可以非常快速地执行简单的字符串相等查询。

Lucene不必针对事务处理进行优化。添加文档时,不必确保查询可以立即看到它。而且它不需要针对现有文档的更新进行优化。

但是,归根结底,如果您真的想知道,则需要阅读源。毕竟,您所引用的两件事都是开源的。


如果我理解正确,那么使文本搜索引擎与众不同的是它们如何处理多词搜索以及如何将搜索结果实时连接到多个索引。我不建议为此咨询Lucene资源。稍微了解一下文本搜索理论可能会更好,@ alienCoder的回答对我有所帮助。
克里斯·杜特罗

1
@bmargulies,如果索引是“每个单词”,那么为什么stackoverflow用户搜索stackoverflow.com/users允许子字符串匹配?
Pacerier,2014年

2
这不是整本书答案的地方。那里有许多关于基本概念的阐述。
bmargulies 2014年

您是什么意思“每个单词的索引” ...如果我开始输入“ abc”,它将如何在文档中找到“ abc”?
亚历山大·米尔斯

1
从单词到文档的索引(B树)可以按文档中的单词搜索文档,因为此类索引的表是(单词,文档),其中索引在单词列上。考虑一个查询,例如:“查找包含单词'police','crime','statistics'的文档。通过搜索单词索引,您可以进行三个log(N)搜索,以获得其中包含这些单词之一的O(N)个文档。然后,您可以执行两个O(N)循环来构建一个包含所有三个单词的文档的集合。虽然这是一个理论上O(N)操作,大多数文件不具有所有三个词,以便其为O(n),其中n <N
Calicoder

34

Lucene创建了一个大索引。索引包含单词ID,出现单词的文档数以及单词在这些文档中的位置。因此,当您提供单个单词查询时,它仅搜索索引(时间复杂度为O(1))。然后使用不同的算法对结果进行排名。对于多单词查询,只需取存在单词的文件集的交集即可。因此,Lucene非常非常快。

有关更多信息,请阅读Google开发人员的这篇文章-http://infolab.stanford.edu/~backrub/google.html


8
略过那张纸,非常有帮助。具体来说,“ 4.5搜索”提供了我一直在寻找的答案。具体地说,这听起来像是对单个单词使用了O(1)哈希搜索,但是随后使用了O(n)扫描将结果限制为40,000个文档。我假设使用了map-reduce算法来拆分此工作,以便用户获得即时结果。
克里斯·杜特罗

一种流行的算法是鸽子等级算法。尽管我对此并不了解。
AlienCoder 2014年

3
那篇论文很有趣:“在本文中,我们介绍了Google,一个原型……”。我想Google并不总是一家大型公司。
Buttons840 2014年

不知道Lucene,但有一个问题:每次搜索都会发生排名?还是保持文件预排名?如果它事先按等级维护文档,如何对多词查询进行维护?
维卡斯·普拉萨德

现在链接已断开。@alienCoder
CEGRD

20

一句话:建立索引。

Lucene会为您的文档创建一个索引,使其可以更快地进行搜索。

列表O(N)数据结构和哈希表O(1)数据结构之间的区别相同。该列表必须遍历整个收藏集以找到您想要的东西。哈希表具有一个索引,可以使它准确地找出所需项的位置,并简单地将其提取。

更新:

我不确定“ Lucene索引搜索比mysql索引搜索快得多”的意思。

我的猜测是您正在使用MySQL“ WHERE document LIKE'%phrase%'”来搜索文档。如果是这样,则MySQL必须在每行上进行表扫描,该表将为O(N)。

Lucene可以将文档解析为标记,按照您的指示将它们分组为n-gram,并为每个标记计算索引。在索引的Lucene文档中找到单词是O(1)。


10
是的,我了解索引部分,但是,Lucene索引搜索比mysql索引搜索快很多。情况如何
Midhat 2010年

8

Lucene使用术语频率和逆文档频率。它创建一个索引,将每个单词与文档以及它的频率计数映射为文档上的反索引。

范例

文件1:随机存取存储器是主存储器。

文件2:硬盘是辅助内存。

Lucene创建一个反向索引,例如

文件1:

期限:随机

频率1

位置:0

期限:记忆

频率2

职位:3

位置:6

因此,它能够快速搜索和检索搜索到的内容。当搜索查询的匹配项过多时,它将根据权重输出结果。考虑搜索查询“ Main Memory”,它会分别搜索所有4个单词,结果将是:

主要

档案1:频率-1

记忆

档案1:频率-2

档案2:频率-1

结果将是File1,然后是File2。为了不再被诸如“和”,“或”之类的最常见单词的权重所困扰,它考虑了文档的倒序频率(即,它降低了文档集中最受欢迎的单词的权重)。

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.