In my previous, we searched for a Sitecore item based on
item id in Azure search index. Let us take a different example this time to see
how to achieve search term highlighting in your project if you are using Azure
search.
Suppose we have a FAQ page where a user can search for
frequently asked questions. We created a
template for FAQ item with fields Question and Answer. Now suppose I want to
search “Working hours” in the FAQ list I will fire below query in Azure Search
Explorer:-
search=working hours&$select=question,answer&$filter=template_1
eq 'a68fcde9c8e34172aeac251f315ca7e5' and
language_1 eq 'en'
In above query:-
1. Search term is working hours
2. Field to retrieve are question and answer
3. We are filtering the results based on the
template id of FAQ Item and English language
4.
Let us
update search parameter class which we created in previous post
public class SearchParams
{
public SearchParams()
{
SortBy = new List<SortQuery>();
FieldsToSearch = new List<string>();
FieldsToRetrieve = new List<string>();
SearchFilterQuery = new List<Tuple<string, string, string, string>>();
Skip = 0;
Top = 100000;
FieldsToHighlight = new List<string>();
HighlightPreTag = "<b>";
HighlightPostTag = "</b>";
}
public List<Tuple<string,string,string,string>> SearchFilterQuery { get; set; }
public int Top { get; set; }
public int Skip { get; set; }
public IList<SortQuery> SortBy { get; set; }
public IList<string> FieldsToSearch { get; set; }
public IList<string> FieldsToRetrieve { get; set; }
public bool IncludeTotalResultCount { get; set; }
public IList<string> FieldsToHighlight { get; set; }
public string HighlightPreTag { get; set; }
public string HighlightPostTag { get; set; }
}
5. Now add fields in which you want to
highlight the search text.
public List<FaqItem> GetFaqBySearchTerm(string searchTerm, string language)
{
LoggerHelper.WriteDebug("GetFaqBySearchTerm method:
Started");
var faqItems = new Lsit<FaqItem>();
try
{
var fieldsToretrieve
= new List<string>();
fieldsToretrieve.Add(Constants.Question);
fieldsToretrieve.Add(Constants.Answer);
var results = GetFaqFromAzure(searchTerm,
Constants.FaqTemplateId, fieldsToretrieve, language);
if (results
!= null &&
results.Results.Count > 0)
{
foreach (var item in results.Results)
{
FaqItem faq = new FaqItem();
faq.Question
= item.Document.Question;
if (item.Highlights != null &&
item.Highlights.ContainsKey(Constants.Question))
{
var highlights =
item.Highlights[Constants.SearchFaqTitleField];
faq.Title =GetHighlighedString(faq.Title,
highlights);
}
faq.Answer = item.Document.Answer;
if (item.Highlights != null &&
item.Highlights.ContainsKey(Constants.Answer))
{
var highlights = item.Highlights[Constants.Answer];
faq.Description =GetHighlighedString(faq.Answer,
highlights);
}
faqItems.Add(faq);
}
}
}
catch (Exception exc)
{
LoggerHelper.WriteDebug(string.Format("GetFaqBySearchTerm method
Exception occured", exc.Message));
throw;
}
LoggerHelper.WriteDebug("GetFaqBySearchTerm method:
End");
return faqItems;
}
private DocumentSearchResult<FaqSearchResult> GetFaqFromAzure(string searchTerm, string templateId,
List<string>
fieldsToretrieve, string language = "en", List<SortQuery> sortQueries = null)
{
DocumentSearchResult<LinkBoxSearchResult> response = null;
if (!string.IsNullOrEmpty(searchTerm)
&& !string.IsNullOrEmpty(templateId))
{
string searchText =
Constants. searchTerm;
SearchParams searchParameters = new SearchParams();
//Filter For language
searchParameters.SearchFilterQuery.Add(new Tuple<string, string, string, string>(Constants.LanguageField,
Convert.ToString(Enums.SearchOperator.eq), "'" +
language + "'", Enums.MultiCriteriaOperation.and.ToString()));
//Filter For template
searchParameters.SearchFilterQuery.Add(new Tuple<string, string, string, string>(Constants.TemplateField,
Convert.ToString(Enums.SearchOperator.eq), "'" +
GenericUtilities.GetAzureFormattedGuid(templateId) + "'", string.Empty));
////Field That We want to Show records in View Page
searchParameters.FieldsToRetrieve = fieldsToretrieve;
searchParameters.FieldsToHighlight.Add(Constants.Question);
searchParameters.FieldsToHighlight.Add(Constants.Answer);
//How many records want to display page at a time
searchParameters.Top = 1;
//If Skip Count has any count value
searchParameters.Skip = 0;
if (sortQueries
!= null)
searchParameters.SortBy = sortQueries;
response = GetFaq(searchTerm, searchParameters);
}
return response;
}
private DocumentSearchResult<FaqSearchResult>
GetFaq(string query,
SearchParams searchParams)
{
ISearchIndexClient searchIndexClient =
SearchServiceOperations.CreateSearchIndexClient();
SearchParameters parameters = new SearchParameters()
{
Filter = QueryBuilder.GenerateFilterQuery(searchParams.SearchFilterQuery),
OrderBy = QueryBuilder.GetSelectedSort(searchParams),
QueryType = QueryType.Full,
SearchFields = searchParams.FieldsToSearch,
IncludeTotalResultCount = searchParams.IncludeTotalResultCount,
Select = searchParams.FieldsToRetrieve,
Skip = searchParams.Skip,
Top = searchParams.Top,
HighlightFields=searchParams.FieldsToHighlight,
HighlightPreTag=searchParams.HighlightPreTag,
HighlightPostTag=searchParams.HighlightPostTag
};
return searchIndexClient.Documents.Search<LinkBoxSearchResult>(query,
parameters);
}
private string GetHighlighedString(string value, IList<string> highlights)
{
if (!string.IsNullOrEmpty(value) &&
highlights.Any())
{
var hits = highlights.Select(h => h.Replace("<b>", string.Empty)
.Replace("</b>", string.Empty)).ToList();
for (int i = 0; i < highlights.Count; i++)
{
value =
value.Replace(hits[i], highlights[i]);
}
}
return value;
}
}