类似Google的自动完成的一种方法是在Supr 1.4中结合带状疱疹和termvector组件。
首先,我们使用带状疱疹组件生成所有n-gram分布,然后使用termvector获得与用户术语序列最接近的预测(基于文档频率)。
架构:
<fieldType name="shingle_text_fivegram" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.LowerCaseTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="false" />
<filter class="solr.ShingleFilterFactory" maxShingleSize="5" outputUnigrams="false"/>
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
</analyzer>
</fieldType>
Solr config:
<searchcomponent name="termsComponent" class="org.apache.solr.handler.component.TermsComponent"/>
<requesthandler name="/terms" class="org.apache.solr.handler.component.SearchHandler">
<lst name="defaults">
<bool name="terms">true</bool>
<str name="terms.fl">shingleContent_fivegram</str>
</lst>
<arr name="components">
<str>termsComponent</str>
</arr>
</requesthandler>
通过上面的设置,我需要在n-gram的边缘上的任何地方删除停用词,并将它们保持在n-gram序列中。
让我们说从“印度和中国”的序列我需要以下顺序:
india
china
india and china
并跳过其余部分。
是否可以与其他Solr组件/过滤器结合使用?
UPD:这是Lucene 4中的一个可能的解决方案(应该可以连接到SOLR):
“你不能制作一个自定义停止过滤器,只在开始时删除停用词(看到的第一个令牌)或输入结束(之后没有看到非停用词令牌)?它需要一些缓冲/ state keep(capture / restorteState)但似乎可行吗?“ - Michael McCandless
来自:http://blog.mikemccandless.com/2013/08/suggeststopfilter-carefully-removes.html
答案 0 :(得分:1)
在Solr 1.4中进行多字自动完成的最佳方法是使用EdgeNGramFilterFactory,因为您需要在用户输入时匹配它。所以你需要匹配“i”,“in”“ind”等等来暗示印度。
答案 1 :(得分:1)
使用单独的查询分析器和KeywordTokenizerFactory,因此(使用您的示例):
<analyzer type="index">
<tokenizer class="solr.LowerCaseTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="false" />
<filter class="solr.ShingleFilterFactory" maxShingleSize="5" outputUnigrams="false"/>
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="false" />
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
</analyzer>