If you are about to implement an auto-compelte text box for your search page, then you are in the right place. This article will show you how to display search suggestions using Sitecore 7 and Solr Search Provider. Solr is a very powerful search platform which provides many indexing and query time analyzers. The NGram analyzer is used here to implement search auto-complete feature. Before I go through the details, please don’t do the following:
Don’t use String.Contains()
var context = index.CreateSearchContext();
var results = context.GetQueryable().Where(i=> i.Title.Contains(searchText));
...
Please don’t ever do this, your client will come back complaining that, when their customers search for “pen” they get irrelevant suggestions such as “Dispenser”, “Open” and “Sharpener”.
Don’t use String.StartsWith()
var context = index.CreateSearchContext();
var results = context.GetQueryable().Where(i=> i.Title.StartsWith(searchText));
...
This won’t work as well because it will fail to return results such as “blue pen” where the title doesn’t start with the word “pen”.
The proper way (Using NGram)
These are the steps to properly implement this feature:
1. Create a type in Sitecore for the auto-complete field.
Open the Sitecore.ContentSearch.Solr.Indexes.config and add the following type match
<typeMatch typeName="autoComplete" type="System.String" fieldNameFormat="{0}_ac" settingType="Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration, Sitecore.ContentSearch.SolrProvider" />
2. Use a Computed field to create a copy of the title using the new data type
Also, you can use copy fields. However, I prefer to use computed fields because they are more flexible. Your computed field should be something like:
public class AutoCompleteTitle : IComputedIndexField { public object ComputeFieldValue(IIndexable indexable) { if (indexable == null) throw new ArgumentNullException("indexable"); var scIndexable = indexable as SitecoreIndexableItem; if (scIndexable == null) { Log.Warn( this + " : unsupported IIndexable type : " + indexable.GetType(), this); return false; } var item = (Item)scIndexable; if (item == null) { Log.Warn( this + " : unsupported SitecoreIndexableItem type : " + scIndexable.GetType(), this); return false; } if (String.Compare(item.Database.Name, "core", StringComparison.OrdinalIgnoreCase) == 0) { return false; } return item.GetValue("Title"); } public string FieldName { get; set; } public string ReturnType { get; set; } }
Don’t forget to add this field to the Sitecore Solr config file “Sitecore.ContentSearch.Solr.Indexes.config” under the element as follows:
<field fieldName="smartsearch" returnType="autoComplete">YourNameSpace.AutoCompleteTitle, YourAssembly</field>
3. Update the Solr schema to support the new data type
You will need to update the Solr schema file so that Solr can apply the NGram analyzer to the new datatype. You will need to add a new dynamic field:
<fieldType name="auto_complete" class="solr.TextField" positionIncrementGap="100"> <analyzer type="index"> <tokenizer class="solr.StandardTokenizerFactory" /> <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" /> <filter class="solr.LowerCaseFilterFactory" /> <filter class="solr.EdgeNGramFilterFactory" minGramSize="3" maxGramSize="20" side="front"/> </analyzer> <analyzer type="query"> <tokenizer class="solr.StandardTokenizerFactory" /> <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" /> <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true" /> <filter class="solr.LowerCaseFilterFactory" /> </analyzer> </fieldType>
Note: Solr needs to be restarted to read the updated schema.
4. Write the search query
Finally, your search code should be something like:
using (var context = index.CreateSearchContext()) { var dataQuery = context.GetQueryable() .Where(i => i["smartsearch_ac"] == searchQuery); var results = dataQuery.GetResults(); ... }
Excellent post!
Very interesting info!Perfect just what I was searching for!
Setting for schema is not relevant for Solr 5
this link should help
http://stackoverflow.com/questions/28772732/edgengram-error-instantiating-class-org-apache-lucene-analysis-ngram-edgengra
shortly side=”front” should be removed