I'm trying to build a generic Search method GetSearchResults
that would fetch results from Solr.
Sample use Case: Get a list of all products where the searchTerm
can be in the Title
OR Description
field AND other facet filters like Color, brand etc.
What would be the recommended approach among these:
- First get all products from Solr and then filter by criteria in the caller method.
- Build the query predicate in the caller method & pass it as an argument to the Solr method.
If there is any other better approach, please let me know.
Approach 1: Get all products from Solr and then filter by criteria in the caller method.
public List<T> GetSearchResults<T>(string searchIndexName, List<string> templateNames, string languageIsoCode) where T : SearchResultItem
{
ISearchIndex searchIndex = ContentSearchManager.GetIndex(searchIndexName);
using (IProviderSearchContext context = searchIndex.CreateSearchContext())
{
var query = PredicateBuilder.True<T>();
if (templateNames != null && templateNames.Count > 0)
{
foreach(string templateName in templateNames)
{
query = query.Or(x => x.TemplateName.Equals(templateName, StringComparison.InvariantCultureIgnoreCase));
}
}
if (!string.IsNullOrWhiteSpace(languageIsoCode))
{
query = query.And(x => x.Language.Equals(languageIsoCode, StringComparison.InvariantCultureIgnoreCase));
}
IQueryable<T> results = context.GetQueryable<T>().Where(query);
return results != null ? results.ToList() : null;
}
}
public void CallerMethod(string searchTerm, List<KeyValuePair<string, string>> facets)
{
List<ProductSearchRelatedItem> results = GetSearchResults<ProductSearchRelatedItem >("custom_index", null, "en")
foreach(ProductSearchRelatedItem psri in results)
{
/// process the filtering logic here
}
}
Approach 2: Build the query predicate in the caller method & pass it as an argument to the Solr method.
public List<T> GetSearchResults<T>(string searchIndexName, Expression<Func<T, bool>> query) where T : SearchResultItem
{
ISearchIndex searchIndex = ContentSearchManager.GetIndex(searchIndexName);
using (IProviderSearchContext context = searchIndex.CreateSearchContext())
{
IQueryable<T> results = context.GetQueryable<T>().Where(query);
return results != null ? results.ToList() : null;
}
}
public void CallerMethod(string searchTerm, List<KeyValuePair<string, string>> facets)
{
var query = PredicateBuilder.True<T>();
/// build all the query AND/OR logic here
......
List<ProductSearchRelatedItem> results = GetSearchResults<ProductSearchRelatedItem >("custom_index", query)
}