Unwanted Lucene Search Results in EpiServer Commerce R2
Issue: User was
getting unexpected search results for products, e.g. with a search key word ‘Sate’ he was getting
same result as for ‘Site’. Although for most of the clients they will happy
with these results but this particular client was unhappy with this result due
to their business requirements. We do not have any word like ‘Sate’ in our
Database or in Index file for Lucene. Clearly it was Fuzzy search that was causing
this although in code we have set FuzzySearch = false;
Reason:
//
Perform Lucene search
SearchResults results =
searchFilterHelper.SearchEntries(criteria) as SearchResults;
In the Mediachase.Commerce.Website, Version=5.2.243.2, SearchFilterHelper's
SearchEntries() method, below:
public virtual ISearchResults SearchEntries(CatalogEntrySearchCriteria
criteria) { try {
_Results = Manager.Search(criteria);
}
catch
(SystemException)
{
if
(HttpContext.Current.IsDebuggingEnabled)
throw;
}
// Perform fuzzy
search if nothing has been found
if (_Results.TotalCount
== 0) {
criteria.IsFuzzySearch = true;
criteria.FuzzyMinSimilarity = 0.7f;
_Results =
Manager.Search(criteria);
}
return _Results;
}
As you can see there is an initial call to
Manager.Search().
Before returning, the TotalCount property on the
ISearchResults object returned is checked to see if there were no results.
If there are no results a fuzzy search is done.
That was causing the issue although iSFuzzySearch was false at the time of request.
Fix: A fix is
present in Episerver Commerce R2 Sp2. There is an extra Function is available that
can be used to stop FuzzySearch if no result is found with actual keyword.
public virtual ISearchResults SearchEntries(CatalogEntrySearchCriteria
criteria, bool isFuzzySearch, float minSimilarity)
//
Perform Lucene search
SearchResults results =
searchFilterHelper.SearchEntries(criteria,false,0) as SearchResults;
Special thanks to Jeff from EpiServer’s Developer Support
team to find out the reason and fix.
Example Code:
internal CatalogIndexSearchDataSource CreateDataSource(SearchFilterHelper filter, int pageNo, int pageSize, ref int totalRows, bool cacheResults, int cacheTime, string nodeString, string keywords, List<string> metaClasses)
{
var currentCulture = Thread.CurrentThread.CurrentUICulture;
Thread.CurrentThread.CurrentUICulture = new CultureInfo(SiteContext.Current.LanguageName);
var recordsToRetrieve = pageSize;
//cache
timeout
TimeSpan cacheTimeout = new TimeSpan(0, (int)cacheTime, 0);
//
Perform search
SearchSort sortObject = null;
// Put
default sort order if none is set
if (sortObject == null)
sortObject = CatalogEntrySearchCriteria.DefaultSortOrder;
var criteria = filter.CreateSearchCriteria(keywords,
sortObject);
//If
meta classes are given to search.
if (metaClasses != null)
foreach (string metaClass in metaClasses)
criteria.SearchIndex.Add(metaClass);
//Add
catalogs
foreach (var row in CatalogContext.Current.GetCatalogDto(SiteContext.Current.SiteId).Catalog)
{
if (row.IsActive && row.StartDate <= FrameworkContext.Current.CurrentDateTime
&& row.EndDate >= FrameworkContext.Current.CurrentDateTime)
criteria.CatalogNames.Add(row.Name);
}
//add
catalog nodes
if (!string.IsNullOrEmpty(nodeString))
{
foreach (string outline in SearchFilterHelper.GetOutlinesForNode(nodeString))
{
criteria.Outlines.Add(outline);
}
}
CatalogIndexSearchDataSource dataSource = null;
// No
need to perform search if no catalogs specified
if (criteria.CatalogNames.Count != 0)
{
Entries entries = new Entries();
//
Perform Lucene search
SearchResults results = searchFilterHelper.SearchEntries(criteria,false,0) as SearchResults;
// Get
IDs we need
int[]
resultIndexes = results.GetIntResults(pageNumber , maxRows+5); // we add padding here to accomodate entries that might
have been deleted since last indexing
if (resultIndexes.Length > 0)
{
int[] productResultIndexes = RefinementHelper.GetParentProducts(pageSize, pageNumber, resultIndexes, ref totalRows);
//
Retrieve actual entry objects, with no caching
entries = CatalogContext.Current.GetCatalogEntries(productResultIndexes,
false, new TimeSpan(), responseGroup);
//
Add in attribute information
AddAttributes(entries,
results);
//
Insert to the cache collection
entries.TotalResults =
totalRows;
CatalogCache.Insert(cacheKey, entries, cacheTimeout); dataSource = new CatalogIndexSearchDataSource {
TotalResults = totalRows, CatalogEntries = entries };
}
Thread.CurrentThread.CurrentUICulture = currentCulture;
return dataSource;
}
Comments
Post a Comment