How to have Solr autocomplete on whole phrase - so

2019-08-25 03:59发布

问题:

I'm creating suggest like google. for now, when i write "do", solr returns "dog", "doll", it returns only one word on schema field. What i want is if it return whole field like "doggy blah blah", "dog store" etc, that would be nice. here's my schema.xml

<field name = "companyDisplayName" type = "text_auto" multiValued="false" indexed = "true" stored = "false" />

and my schema fieldtype configuration:

<fieldType name="text_auto" class="solr.TextField" positionIncrementGap="100" ><analyzer type="index">
    <tokenizer class="solr.KeywordTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.EdgeNGramFilterFactory" maxGramSize="30" minGramSize="1"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.KeywordTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

Here's my solrconfig.xml

<searchComponent class="solr.SpellCheckComponent" name="suggest">
   <lst name="spellchecker">
      <str name="name">suggest</str>
      <str name="classname">org.apache.solr.spelling.suggest.Suggester</str>
      <str name="lookupImpl">org.apache.solr.spelling.suggest.fst.AnalyzingInfixLookupFactory</str>
      <str name="buildOnCommit">true</str>
      <str name="suggestAnalyzerFieldType">text_auto</str>
      <str name="field">companyDisplayName</str>
   </lst>
</searchComponent>

<requestHandler class="org.apache.solr.handler.component.SearchHandler" name="/suggest">
<lst name="defaults">
    <str name="spellcheck">true</str>
    <str name="spellcheck.dictionary">suggest</str>
    <str name="spellcheck.onlyMorePopular">true</str>
    <str name="spellcheck.count">5</str>
    <str name="spellcheck.collate">false</str>
<str name="echoParams">explicit</str>
<str name="defType">edismax</str>
<str name="rows">10</str>
<str name="fl">companyDisplayName</str>
<str name="qf">companyDisplayName^30</str>
<str name="pf">companyDisplayName^50.0</str>
<str name="group">true</str>
<str name="group.field">companyDisplayName</str>
<str name="sort">score desc</str>
<str name="group.sort">score desc</str>
</lst>
<arr name="components">
    <str>suggest</str>
</arr>

and my query:

http://localhost:8983/solr/vw_search_company_with_buildings/suggest?spellcheck.q=hunn

回答1:

There multiple changes you need to make for your suggester to get working.

Use stored=true for the filed you want to use in suggestion. I would suggest you to copy the field in another field using copyField tag. You need not to index the copied field. You can replace the text_general definition in your schema.xml. It is same as default, but a simpler version.

<field name = "suggest_field" type = "text_general" multiValued="false" indexed = "false" stored = "true" />

<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
    <analyzer>
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
        <filter class="solr.LowerCaseFilterFactory"/>
    </analyzer>
</fieldType>

Now use the following configuration for suggester searchComponent and requestHandler. This configuration uses solr.SuggestComponent instead of solr.SpellCheckComponent. For AnalyzingInfixLookupFactory default highlighting is true, here it is false. I have added <str name="dictionaryImpl">DocumentDictionaryFactory</str> for getting the complete attribute value in the suggester.

<searchComponent name="suggest" class="solr.SuggestComponent">
<lst name="suggester">
    <str name="name">suggest</str>
    <str name="lookupImpl">AnalyzingInfixLookupFactory</str>
    <str name="dictionaryImpl">DocumentDictionaryFactory</str>
    <str name="field">suggest_field</str>
    <str name="suggestAnalyzerFieldType">text_general</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.dictionary">suggest</str>
    <str name="suggest.count">10</str>
    <str name="suggest.onlyMorePopular">true</str>
    <str name="suggest.count">5</str>
    <str name="suggest.collate">false</str>
    <str name="echoParams">explicit</str>
    <str name="defType">edismax</str>
    <str name="rows">10</str>
    <str name="fl">suggest_field</str>
    <str name="qf">suggest_field^30</str>
    <str name="pf">suggest_field^50.0</str>
    <str name="group">true</str>
    <str name="group.field">suggest_field</str>
    <str name="sort">score desc</str>
    <str name="group.sort">score desc</str>
</lst>
<arr name="components">
    <str>suggest</str>
</arr>
</requestHandler>

Use the following command to make the suggestion requests. This contains suggest.build=true in the url, which mean it will build the dictionary every time you make request. You can remove it for your production purpose.

http://localhost:8983/solr/vw_search_company_with_buildings/suggest?suggest.build=true&suggest.q=do

PS : There is issue with AnalyzingInfixLookupFactory that, it lock the suggestion dictionary directory when you reload it second time. You can use indexPath for solving the issue.

Here is the reference link.



标签: xml solr