lucene使用的字符串匹配算法

时间:2010-02-05 16:31:28

标签: java algorithm lucene string-matching

我想知道Apache Lucene使用的字符串匹配算法。我一直在浏览由here给出的lucene使用的索引文件格式。似乎lucene存储文本中出现的所有单词,以及每个文档中出现的频率。 但据我所知,对于有效的字符串匹配,它需要预处理文档中出现的单词。

例如: 搜索“iamrohitbanga是stackoverflow的用户”(使用模糊匹配)

在某些文件中。

可能有一个包含字符串“rohit banga”

的文档

发现搜索字符串中存在子字符串rohit和banga,它会使用一些有效的子字符串匹配。

我想知道它是哪种算法。如果它做了一些预处理,java api中的函数调用会触发它。

3 个答案:

答案 0 :(得分:6)

正如Yuval解释的那样,一般来说,Lucene适合完全匹配(通过在索引和查询时使用分析器对术语进行规范化)。

在Lucene主干代码中(尚未发布任何版本)实际上对于不正确的匹配(例如Regex,Wildcard和Fuzzy)存在后缀树使用。

这种方式的工作方式是Lucene术语词典本身实际上是后缀树的一种形式。您可以在几个地方提到的文件格式中看到这一点:

  

因此,如果前一个术语的文本是“骨骼”而术语是“boy”,则PrefixLength为2,后缀为“y”。

术语info索引通过以特定间隔(默认情况下每128个术语)索引此树为我们提供“随机访问”。

如此低级别它是一个后缀树,但在更高级别,我们利用这些属性(主要是在IndexReader.terms中指定的属性将术语字典视为确定性有限状态自动机(DFA):

  

返回从给定术语开始的所有术语的枚举。如果给定的术语不存在,则枚举位于第一个术语大于提供的术语。枚举由Term.compareTo()排序。每个术语都大于枚举中它前面的所有术语。

Regex,Wildcard和Fuzzy等不精确的查询本身也被定义为DFA,“匹配”只是DFA交集。

答案 1 :(得分:2)

Lucene的基本设计使用精确的字符串匹配,或使用Analyzer定义等效的字符串。分析器将文本分解为可索引的标记。在此过程中,它可以整理等效的字符串(例如大写和小写,词干串,删除变音符号等) 生成的标记作为字典存储在索引中,加上文档中标记的发布列表。因此,您可以构建和使用Lucene索引,而无需使用字符串匹配算法(如KMP)。 但是,FuzzyQueryWildCardQuery使用类似的内容,首先搜索匹配的字词,然后使用它们进行完全匹配。有关解决此问题的新方法,请参阅Robert Muir's Blog Post about AutomatonQuery

答案 2 :(得分:0)

正如您所指出的,Lucene只存储文档中出现的术语列表。 Lucene如何提取这些词语取决于你。默认的lucene分析器简单地打破由空格分隔的单词。您可以编写自己的实现,例如源字符串'iamrohitbanga'产生5个令牌:'iamrohitbanga','我','am','rohit','banga'。

请查看TokenFilter类的lucene API文档。