6

We are running Sitecore 8.0 and Solr 4.10.3. I'm trying to get text search working where if I search for play, player and plays are also returned in the search results.

I can't find reference on how to achieve this. The current search that I have configured just does a straight text lookup and only returns results with play.

Do I need to create a analyzer in Solr with one of the stemming algorithms to achieve this?

I'm using the contains function to run the text search in Sitecore search api.

6

You can do this on the SOLR configuration site. To setup stemming in SOLR you just need to set the tokenizer and analyzer for the field.

For example. Say you have a field in your template called Body Text - rather than use the dynamic SOLR field, you can add this to your schema.xml.

<field name="body_text" type="text_stem" indexed="true" stored="true" multiValued="true"/>

Now we just need to define the field type in the schema and set the tokenizer and filter:

<fieldType name="text_stem">
    <analyzer>
        <tokenizer class="solr.WhitespaceTokenizerFactory"/>
        <filter class="solr.SnowballPorterFilterFactory"/>
    </analyzer>
</fieldType>

What do these do:

  • solr.WhitespaceTokenizerFactory - this will break up the sentences into words using whitespace as the delimeter
  • solr.SnowballPorterFilterFactory - will apply a stemming algorithm to each work or token. There are a number of stemming algorithms, this example uses the Snowball Porter one.

For more examples look at Keyword Stemming and Lemmatisation with SOLR

  • I tried it the same way. Getting mixed results. Maybe my test content is bad – Gabbar Dec 8 '16 at 14:19
  • you may need to use a different stemming algorithm – Richard Seal Dec 8 '16 at 14:48
  • 1
    Should I use the contains keyword with this approach? What about when I have search term like "football play" ? How would I search for that? – Gabbar Dec 8 '16 at 16:34
3

Sure, you could use stemming. But as the simplest approach, you can go with a wildcard query:

using (IProviderSearchContext context = ...)
{
  var searchTerm = "play";

  var query =
    context.GetQueryable<SearchResultItem>()
      .Where(_ => _.FieldName.MatchWildcard(searchTerm + "*"));

  SearchResults<SearchResultItem> results = query.GetResults();
}

Make sure to sanitize the search term beforehand.

  • 1
    Would the wildcard search return "ran", "running", "runs" etc... for the term "run"? - I guess the only one would be "ran" that it might not. – Richard Seal Dec 8 '16 at 14:18
  • 1
    @RichardSeal You are correct, of course. Wildcard queries are not a complete replacement for proper language-aware algorithms. But, in my experience, wildcard queries are good enough for most cases. – Dmytro Shevchenko Dec 8 '16 at 14:21
  • I'll give both a try with good content and report back. Thanks for the input. – Gabbar Dec 8 '16 at 14:30
  • Hum :P I also don't think this qualifies as "stemming". This implementation would match "baskets", "basket" and "basketball", something a proper stemming algorithm would not. – Mark Cassidy Dec 8 '16 at 14:31
  • @MarkCassidy I never claimed that my answer used stemming ;-) – Dmytro Shevchenko Dec 8 '16 at 14:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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