通过带状疱疹和termvector组件自动完成

时间:2011-02-10 08:13:47

标签: autocomplete solr n-gram

类似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

2 个答案:

答案 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>