Skip to content

Instantly share code, notes, and snippets.

@vince-geekcore
Last active September 4, 2015 09:04
Show Gist options
  • Save vince-geekcore/4d48a43fb60d27162641 to your computer and use it in GitHub Desktop.
Save vince-geekcore/4d48a43fb60d27162641 to your computer and use it in GitHub Desktop.
Sitecore ContentSearch example
/// <summary>
/// Get Searchresults with keyword overload for Global Search
/// </summary>
/// <typeparam name="U"></typeparam>
/// <param name="context"></param>
/// <param name="language"></param>
/// <param name="filters"></param>
/// <param name="unfilteredFacets"></param>
/// <param name="applyFacets"></param>
/// <param name="keyword"></param>
/// <returns></returns>
public SearchResults<U> GetSearchResults<U>(IProviderSearchContext context, Language language, NameValueCollection filters, out List<FacetCategory> unfilteredFacets, bool applyFacets, string keyword) where U : ProvinceSearchResult
{
unfilteredFacets = new List<FacetCategory>();
// Start with the default query..
var q = from sr in context.GetQueryable<U>(new CultureExecutionContext(language.CultureInfo))
where sr.Language == language.Name
select sr;
if (!string.IsNullOrWhiteSpace(keyword))
{
var predicate = PredicateBuilder.True<U>();
foreach (var t in keyword.Split(' '))
{
// Ignore stopwords. We define a custom list for skipping on query time to make sure SC ContentSearch
// does not strip too much from index and to circumvent other side effects
if (StopWords.Contains(t.ToLowerInvariant()))
{
continue;
}
var tempTerm = t;
// Query-time boost the title fields from the different templates. If searchterm found in title; boost
predicate = predicate.Or(p => p[(ObjectIndexerKey)"NE_NavigationTitle"].MatchWildcard(tempTerm + "*").Boost(5.5f));
// "Starts with" search for search term (linq startswith does not return results so wildcard is used)
predicate = predicate.Or(p => p.Content.MatchWildcard(tempTerm + "*"));
predicate = predicate.Or(p => p.Content.Equals(tempTerm));
}
// Try to find SearchTerm specific template boost for complete (not splitted) term
string boostTemplateName = RetrieveBoostTemplateByTerm(keyword);
if (!string.IsNullOrWhiteSpace(boostTemplateName))
{
predicate = predicate.Or(p => p.Content.Equals(keyword) && p.TemplateName.Equals(boostTemplateName).Boost(5.0f));
}
// Global tags boost (search term find as exact match in the selected global tags
predicate = predicate.Or(p => p[(string)(ObjectIndexerKey)"zel_globaltags_computed"].Equals(keyword).Boost(5.4f));
// Also search in the facet filters (no boost)
predicate = predicate.Or(p => p[(string)(ObjectIndexerKey)"ng_province_computed"].Equals(keyword));
predicate = predicate.Or(p => p[(string)(ObjectIndexerKey)"ri_type_computed"].Equals(keyword));
q = q.Where(predicate);
}
if (applyFacets)
{
var facetItems = FacetItemHelper.GetFacetItems(Sitecore.Configuration.Factory.GetDatabase("web").GetItem(MainUtil.GetID(Items.ItemIDs.Default.SbbBucketRoot)));
q = FacetItemHelper.FacetOn(q, facetItems);
unfilteredFacets = q.GetFacets().Categories;
}
if (filters != null)
{
q = ApplyGlobalSearchFilters(q, filters, context, language);
}
// Get results..
var results = q.GetResults<U>();
return results;
}
private IQueryable<U> ApplyGlobalSearchFilters<U>(IQueryable<U> q, NameValueCollection filters, IProviderSearchContext context, Language language) where U : ProvinceSearchResult
{
if (!string.IsNullOrEmpty(filters[SearchApi.GlobalSearchSectionQueryStringKey]))
{
var globalSearchSectionQuery = PredicateBuilder.False<U>();
foreach (object result in (filters[SearchApi.GlobalSearchSectionQueryStringKey] ?? string.Empty).Split(','))
{
var facetFieldName = FacetMap[SearchApi.GlobalSearchSectionQueryStringKey];
facetFieldName = facetFieldName.Replace("_facet", "_computed");
globalSearchSectionQuery = globalSearchSectionQuery.Or(x => result == x[(ObjectIndexerKey)facetFieldName]);
}
q = q.Where(globalSearchSectionQuery);
}
return q;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment