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.

2 Answers 2

7

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

3
  • I tried it the same way. Getting mixed results. Maybe my test content is bad
    – Gabbar
    Commented Dec 8, 2016 at 14:19
  • you may need to use a different stemming algorithm
    – Richard Seal
    Commented Dec 8, 2016 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
    Commented Dec 8, 2016 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.

5
  • 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
    Commented Dec 8, 2016 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. Commented Dec 8, 2016 at 14:21
  • I'll give both a try with good content and report back. Thanks for the input.
    – Gabbar
    Commented Dec 8, 2016 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
    Commented Dec 8, 2016 at 14:31
  • @MarkCassidy I never claimed that my answer used stemming ;-) Commented Dec 8, 2016 at 14:33

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.