lucene(9)—lucene搜索之拼写检查和相似度查询提示(spellcheck)
suggest应用场景
用户的输入行为是不确定的,而我们在写程序的时候总是想让用户按照指定的内容或指定格式的内容进行搜索,这里就要进行人工干预用户输入的搜索条件了;我们在用百度谷歌等搜索引擎的时候经常会看到按键放下的时候直接会提示用户是否想搜索某些相关的内容,恰好lucene在开发的时候想到了这一点,lucene提供的suggest包正是用来解决上述问题的。
suggest包联想词相关介绍
suggest包提供了lucene的自动补全或者拼写检查的支持;
拼写检查相关的类在org.apache.lucene.search.spell包下;
联想相关的在org.apache.lucene.search.suggest包下;
基于联想词分词相关的类在org.apache.lucene.search.suggest.analyzing包下;
拼写检查原理
Lucene的拼写检查由org.apache.lucene.search.spell.SpellChecker类提供支持;
SpellChecker设置了默认精度0.5,如果我们需要细粒度的支持可以通过调用setAccuracy(float accuracy)来设定;
spellChecker会将外部来源的词进行索引;
这些来源包括:
DocumentDictionary查询document中的field对应的值;
FileDictionary基于一个文本文件的Directionary,每行一项,词组之间以"\t" TAB分隔符进行,每项中不能含有两个以上的分隔符;
HighFrequencyDictionary从原有的索引文件中读取某个term的值,并按照出现次数检查;
LuceneDictionary也是从原有索引文件中读取某个term的值,但是不检查出现次数;
PlainTextDictionary从文本中读取内容,按行读取,没有分隔符;
其索引的原理如下:
对索引过程加syschronized同步;
检查Spellchecker是否已经关闭,如果关闭,抛出异常,提示内容为:Spellchecker has been closed;
对外部来源的索引进行遍历,统计被遍历的词的长度,如果长度小于三,忽略该词,反之构建document对象并索引到本地文件,创建索引的时候会对每个单词进行详细拆分(对应addGram方法),其执行过程如下所示
|
|
对词语进行遍历拆分的方法为addGram,其实现为:
查看代码可知,联想词的索引不仅关注每个词的起始位置,也关注其倒数的位置;
联想词查询的时候,先判断grams里边是否包含有待查询的词拆分后的内容,如果有放到结果SuggestWordQueue中,最终结果为遍历SuggestWordQueue得来的String[],其代码实现如下:
|
|
|
|
编程实践
以下是我根据FileDirectory相关描述编写的一个测试程序
|
|
其中,我用的suggest.txt内容为:
|
|
测试结果为:
|
|