search - Google 喜欢使用 Solr 进行自动提示/预先输入(建议关键字/短语)

标签 search solr autocomplete typeahead

要求
我需要在搜索框中提供类似 google 的建议。 Solr 已经是给定的。
结果应如下所示:
搜索词亚历克斯
结果 亚历山大·贝林,亚历山大·某人...
搜索词出租车
结果 电缆,高压电缆,电缆剪
enter image description here
目的是将短语作为建议,而不是整个字段或摘录。查询应该不区分大小写,亚历克斯 应该具有与 相同的结果亚历克斯 ,但搜索结果(建议)必须有原始大小写。
建议必须是可按类别过滤 ,我们在一个索引中有多个域的结果,结果应该由包含域的特定字段过滤。 上下文字段 仅适用于“AnalyzingInfixLookupFactory 和 BlendedInfixLookupFactory 当前支持此功能,当由 DocumentDictionaryFactory 支持时。”
我尝试了三种方法
1.方法:FreeTextLookupFactory

config (no special schema changes): 
     <searchComponent name="suggest" class="solr.SuggestComponent">
        <lst name="suggester">
          <str name="name">default</str>
          <str name="lookupImpl">FreeTextLookupFactory</str> 
          <str name="dictionaryImpl">DocumentDictionaryFactory</str>
          <str name="field">content</str>
          <str name="ngrams">3</str>
          <str name="separator"> </str>
          <str name="suggestFreeTextAnalyzerFieldType">text_general</str>
        </lst>
    </searchComponent>

    <requestHandler name="/suggest" class="solr.SearchHandler" startup="lazy" >
      <lst name="defaults">
        <str name="suggest">true</str>
        <str name="suggest.count">10</str>
        <str name="suggest.dictionary">default</str>        
        <str name="echoParams">explicit</str>
      </lst>
      <arr name="components">
         <str>suggest</str>
      </arr>
    </requestHandler>
这很合理,但只能提供单个单词。
搜索词亚历克斯
结果 亚历山大、亚历山德拉……
优点是索引速度非常快。我试图将它与 ShingleFilter 结合起来,但这不起作用,可能是因为 ShingleFilter 已经是 FreeTextLookupFactory 的一部分。因为不支持 FreeTextLookupFactory 类别。
2. 方法 : BlendedInfixLookupFactory 与自定义字段
schema:
<field name="suggest_field" type="text_suggest" indexed="true" stored="true" multiValued="true"/>
<field name="site" type="string" stored="true" indexed="true"/>
<copyField source="content" dest="suggest_field"/>

    <fieldType name="text_suggest" class="solr.TextField" positionIncrementGap="100">
            <analyzer type="index">
                <tokenizer class="solr.StandardTokenizerFactory"/>
                <!--filter class="solr.LowerCaseFilterFactory"/-->
                <filter class="solr.TrimFilterFactory"/>
                <filter class="solr.ShingleFilterFactory" 
                    minShingleSize="2"
                    maxShingleSize="4"
                    outputUnigrams="true"
                    outputUnigramsIfNoShingles="true"/>
            </analyzer>
            <analyzer type="query">
                <tokenizer class="solr.KeywordTokenizerFactory"/>
                <filter class="solr.LowerCaseFilterFactory"/>
                <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
           </analyzer>
    </fieldType>

config:
<searchComponent name="suggest" class="solr.SuggestComponent">
   <lst name="suggester">
      <str name="name">default</str>
      <str name="lookupImpl">BlendedInfixLookupFactory</str>
      <str name="blenderType">position_linear</str>
      <str name="dictionaryimpl">DocumentDictionaryFactory</str>
      <str name="field">suggest_field</str>
      <str name="weightField">weight</str>
      <str name="suggestAnalyzerFieldType">text_suggest</str>
      <str name="queryAnalyzerFieldType">phrase_suggest</str>
      <str name="indexPath">suggest</str>
      <str name="buildOnStartup">false</str>
      <str name="buildOnCommit">false</str>
      <bool name="exactMatchFirst">true</bool>
      <str name="contextField">site</str>
   </lst> 
</searchComponent>

    <requestHandler name="/suggest" class="solr.SearchHandler" startup="lazy" >
      <lst name="defaults">
        <str name="suggest">true</str>
        <str name="suggest.count">10</str>
        <str name="suggest.dictionary">default</str>        
        <str name="echoParams">explicit</str>
      </lst>
      <arr name="components">
         <str>suggest</str>
      </arr>
    </requestHandler>FreeTextLookupFactory

第二种方法导致了我奇怪的行为:
搜索词亚历克斯或亚历克斯
结果 没有 ...
搜索词出租车
结果 电缆、电缆、电压电缆、电缆附件、电力电缆……
使用相同的字段,某些查询没有搜索结果。对于 <10000 个条目,索引速度已经 > 12 小时。由于应支持 BlendedInfixLookupFactory 和 DocumentDictionaryFactory 类别。
但是在查询中使用类别时。 http://localhost:8983/solr/magnolia/suggest?wt=json&suggest=true&suggest.q=nym&suggest.cfq=com结果是空的。字段“site”在索引中多次包含值“com”。
3. 使用 HighFrequencyDictionaryFactory 和自定义字段来处理 BlendedInfixLookupFactory
schema:

 <field name="suggest_field" type="text_shingle" indexed="true" stored="true" multiValued="true"/>
...
<copyField source="_text_" dest="suggest_field"/>
...
    <fieldType name="text_shingle" class="solr.TextField" positionIncrementGap="100">
        <analyzer type="index">
           <charFilter class="solr.HTMLStripCharFilterFactory"/>
           <filter class="solr.TrimFilterFactory"/>
           <tokenizer class="solr.StandardTokenizerFactory"/>
           <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords_suggestions.txt" format="snowball" />
           <!--filter class="solr.EdgeNGramFilterFactory" minGramSize="4" maxGramSize="15"/-->
           <filter class="solr.ShingleFilterFactory" minShingleSize="2" maxShingleSize="4" outputUnigrams="false" outputUnigramsIfNoShingles="true" fillerToken=""/>
        </analyzer>
    </fieldType>
    <!-- marc johnen : used for autocomplete-->
    <fieldType name="text_suggest" class="solr.TextField" positionIncrementGap="100">
          <analyzer>
             <tokenizer class="solr.StandardTokenizerFactory"/>
             <filter class="solr.LowerCaseFilterFactory"/>
             <filter class="solr.TrimFilterFactory"/>
          </analyzer>
    </fieldType>

config:
    <searchComponent name="suggest" class="solr.SuggestComponent">
      <lst name="suggester">
        <str name="name">default</str>
        <str name="lookupImpl">BlendedInfixLookupFactory</str>
        <str name="dictionaryImpl">HighFrequencyDictionaryFactory</str>
        <str name="field">suggest_field</str>
        <str name="suggestAnalyzerFieldType">text_suggest</str>
        <str name="minPrefixChars">2</str>
        <str name="exactMatchFirst">true</str>
        <str name="buildOnStartup">false</str> 
        <str name="buildOnCommit">true</str>
        <str name="highlight">false</str>
      </lst>
    </searchComponent>

    <requestHandler name="/suggest" class="solr.SearchHandler" startup="lazy" >
      <lst name="defaults">
        <str name="suggest">true</str>
        <str name="suggest.count">10</str>
        <str name="suggest.dictionary">default</str>        
        <str name="echoParams">explicit</str>
      </lst>
      <arr name="components">
         <str>suggest</str>
      </arr>
    </requestHandler>
这种方法的结果相当不错,除了一些重复的短语外,基本按照规定,因为有些关键字因为开头或结尾有空格而重复,例如“电源线”和“电源线”。除此之外还不错。
搜索词亚历克斯
结果 亚历山大·贝林,亚历山大·某人...
搜索词出租车
结果 电缆,高压电缆,电缆剪
对于 <10000 个文档,索引很容易花费一天的时间。但主要问题是因为 HighFrequencyDictionaryFactory 类别不受支持。
询问
我使用的查询如下所示:
http://localhost:8983/solr/magnolia/suggest?wt=json&suggest=true&suggest.q=cab
添加 <str name="contextField">site</str>在类别和 &suggest.cfq=com 的配置中适用时查询。

最佳答案

我最终使用了 FreeTextLookupFactory 并为每种语言创建了一个单独的字段和建议器。

关于search - Google 喜欢使用 Solr 进行自动提示/预先输入(建议关键字/短语),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67811839/

相关文章:

php - 快速搜索加密数据?

php - MYSQL LIKE 对于不同的语言有不同的行为,所有表都是utf8

mysql - 按多列中的日期范围搜索

templates - 如何获取 Elasticsearch 5.x 中的搜索模板列表?

java - xsl 到 xml 转换添加不存在的字段?

Solr Suggester - 如何过滤自动完成结果

hadoop - Kerberized环境中需要Solr UI身份验证

c - 为什么我不能在busybox中用 '\t'模拟自动补全

ios - 在谷歌地图中获取城市周围的特定类别

css - Visual Studio Code + 建议 CSS 中的可用值