我想了解Lucene搜索如何如此快速地工作。我在网络上找不到任何有用的文档。如果您有什么需要阅读(缺少Lucene源代码),请告诉我。
在我的情况下,使用带有索引的mysql5文本搜索的文本搜索查询大约需要18分钟。lucene搜索同一查询只需不到一秒钟的时间。
Answers:
Lucene是反向全文索引。这意味着它将获取所有文档,将它们拆分为单词,然后为每个单词建立一个索引。由于索引是完全无序的字符串匹配,因此它可以非常快。假设,SQL上的无序索引varchar
字段可能同样快,实际上,我认为您会发现在这种情况下,大型数据库可以非常快速地执行简单的字符串相等查询。
Lucene不必针对事务处理进行优化。添加文档时,不必确保查询可以立即看到它。而且它不需要针对现有文档的更新进行优化。
但是,归根结底,如果您真的想知道,则需要阅读源。毕竟,您所引用的两件事都是开源的。
Lucene创建了一个大索引。索引包含单词ID,出现单词的文档数以及单词在这些文档中的位置。因此,当您提供单个单词查询时,它仅搜索索引(时间复杂度为O(1))。然后使用不同的算法对结果进行排名。对于多单词查询,只需取存在单词的文件集的交集即可。因此,Lucene非常非常快。
有关更多信息,请阅读Google开发人员的这篇文章-http://infolab.stanford.edu/~backrub/google.html
一句话:建立索引。
Lucene会为您的文档创建一个索引,使其可以更快地进行搜索。
列表O(N)数据结构和哈希表O(1)数据结构之间的区别相同。该列表必须遍历整个收藏集以找到您想要的东西。哈希表具有一个索引,可以使它准确地找出所需项的位置,并简单地将其提取。
更新:
我不确定“ Lucene索引搜索比mysql索引搜索快得多”的意思。
我的猜测是您正在使用MySQL“ WHERE document LIKE'%phrase%'”来搜索文档。如果是这样,则MySQL必须在每行上进行表扫描,该表将为O(N)。
Lucene可以将文档解析为标记,按照您的指示将它们分组为n-gram,并为每个标记计算索引。在索引的Lucene文档中找到单词是O(1)。
Lucene使用术语频率和逆文档频率。它创建一个索引,将每个单词与文档以及它的频率计数映射为文档上的反索引。
范例:
文件1:随机存取存储器是主存储器。
文件2:硬盘是辅助内存。
Lucene创建一个反向索引,例如
文件1:
期限:随机
频率1
位置:0
期限:记忆
频率2
职位:3
位置:6
因此,它能够快速搜索和检索搜索到的内容。当搜索查询的匹配项过多时,它将根据权重输出结果。考虑搜索查询“ Main Memory”,它会分别搜索所有4个单词,结果将是:
主要
档案1:频率-1
记忆
档案1:频率-2
档案2:频率-1
结果将是File1,然后是File2。为了不再被诸如“和”,“或”之类的最常见单词的权重所困扰,它考虑了文档的倒序频率(即,它降低了文档集中最受欢迎的单词的权重)。