1

I'm using Solr 7.2.1, I'm trying to implement the 'Did you mean' feature, I've configured the spell check handler and it's working well, the issue is when trying with multiple words, if only one word was spelled correctly, no results are returned. For example if I write 'drive caq', it returns me empty results, if I write 'caq' as a single word, it returns me the correctly spelled word which is 'car'. I want it t return me correctly spelled collations as 'drive car'

Solr Configurations:

<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
    <str name="queryAnalyzerFieldType">text_general</str>
    <lst name="spellchecker">
      <str name="name">default</str>
      <str name="field">title</str>
      <str name="classname">solr.DirectSolrSpellChecker</str>
      <str name="distanceMeasure">internal</str>
      <float name="accuracy">0.5</float>
      <int name="maxEdits">2</int>
      <int name="minPrefix">1</int>
      <int name="maxInspections">5</int>
      <int name="minQueryLength">3</int>
      <float name="maxQueryFrequency">0.5</float>
    </lst>
  </searchComponent>

<requestHandler name="/spell" class="solr.SearchHandler" startup="lazy">
    <lst name="defaults">
      <str name="spellcheck.dictionary">default</str>
      <str name="spellcheck">on</str>
      <str name="df">title</str>
      <str name="spellcheck.extendedResults">true</str>
      <str name="spellcheck.count">10</str>
      <str name="spellcheck.alternativeTermCount">5</str>
      <str name="spellcheck.maxResultsForSuggest">5</str>
      <str name="spellcheck.collate">true</str>
      <str name="spellcheck.collateExtendedResults">true</str>
      <str name="spellcheck.maxCollationTries">10</str>
      <str name="spellcheck.maxCollations">5</str>
      <str name="spellcheck.build">true</str> 
    </lst>
    <arr name="last-components">
      <str>spellcheck</str>
    </arr>
  </requestHandler>

the code for using the spell check component:

  using (IProviderSearchContext ctx = ContentSearchManager.GetIndex("sitecore_sxa_master_index").CreateSearchContext())
                {
                    var results = ctx.GetSpellCheck(new SolrQuery(Term), new SpellCheckHandlerQueryOptions()
                    {
                        SpellCheck = new SpellCheckingParameters()
                        {
                            Count = 10,
                            Build = true,
                            Collate = true
                        }
                    });
                }

1 Answer 1

2

Replace

<str name="classname">solr.DirectSolrSpellChecker</str>

with

<str name="classname">solr.WordBreakSolrSpellChecker</str>

in <searchComponent name="spellcheck"> node of solrconfig.xml

rebuild dictionary and request spell checking like:

var results = ctx.GetSpellCheck(new SolrQuery(Term), new SpellCheckHandlerQueryOptions()
{
    SpellCheck = new SpellCheckingParameters()
    {
        Count = 10,
        Build = true,
        Collate = true
    }
});

if (results != null && results.SpellChecking != null && results.SpellChecking.Count > 0)
{
    var words = terms.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
    if (words.Length < 2)
    {
        return results.SpellChecking.SelectMany(x => x.Suggestions);
    }

    var correct = "";
    foreach (var w in words)
    {
        var suggest = results.SpellChecking.FirstOrDefault(x => x.Query.Equals(w));
        if (suggest != null && suggest.Suggestions.Any())
        {
            correct += suggest.Suggestions.First() + " ";
        }
        else
        {
            correct += w + " ";
        }
    }
    return new List<string> { correct.Trim() };
}
return new List<string>();

Update

As you mentioned in comments, /spell?q=title:term works only if term is one word. It is not so. When you spell checking by multiple words you can catch error undefined field _text_ because it is default configuration of <initParams path="/spell>. Just relpace initparams for spellchecking in solrconfig.xml with:

  <initParams path="/spell">
    <lst name="defaults">
      <str name="df">title</str>
    </lst>
  </initParams>

Your query to Solr will look similar to

/spell?q=:word1 word2 word3&start=0&rows=5&fl=title&fq=_indexname:(your_index_name)&spellcheck=true&spellcheck.count=5

and it should works fine (it works for me).

enter image description here

I also noticed that your use field name title without any postfix, it is ok if it is your custom configuration. If not, your should use it with postfix like title_t (the same name as you see in solr) in all definitions in solrconfig.xml.

6
  • I tried it, I used WordBreakSolrSpellChecker and rebuilt the dictionary, but no data returned at all, I tried even using the solr '/spell' endpoint, but no results returned also. Commented Aug 4, 2020 at 5:16
  • I found the issue, I'm using the Sitecore API, so I looked at its code, the parameter used for adding the query is 'q', it's hardcoded so it'll always be 'q', I tried the '/spell' endpoint at Solr, the 'q' parameter works fine with one word only, for multiple words 'spellcheck.q' should be used, I don't know how to override or change this honestly. Commented Aug 4, 2020 at 5:35
  • @MohamedYaseen, I updated my answer, try to define initparams for spellchecker.
    – x3mxray
    Commented Aug 4, 2020 at 8:57
  • yes it worked, thank you so much, it works perfect now. Commented Aug 4, 2020 at 9:03
  • I have another issue don't know to post it in another question or not, the 'title' field I use has few values, when I use other field with more than 2k values, no results are returned Commented Aug 4, 2020 at 9:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.