Skip to content

Instantly share code, notes, and snippets.

@StephenPAdams
Created July 14, 2016 15:59
Show Gist options
  • Save StephenPAdams/0381895d0a1b0cc1e96d16ea4bd743ec to your computer and use it in GitHub Desktop.
Save StephenPAdams/0381895d0a1b0cc1e96d16ea4bd743ec to your computer and use it in GitHub Desktop.
Examine Product Search
/// <summary>
/// Retrieves products by product category ids, tag ids, etc.
/// </summary>
/// <param name="productCategoryIds"></param>
/// <param name="tagIds"></param>
/// <param name="memberTypeIds"></param>
/// <param name="maxItems"></param>
/// <param name="pageNumber"></param>
/// <param name="pagingInfo"></param>
/// <param name="sortBy"></param>
/// <param name="priceLower"></param>
/// <param name="priceUpper"></param>
/// <param name="manufacturerId"></param>
/// <param name="loadVariations"></param>
/// <param name="viewAll"></param>
/// <param name="loadNotDirectlyPurchasable">If true, items that aren't directly purchasable will be loaded</param>
/// <param name="loadPriceMatrices"></param>
/// <returns></returns>
public IList<Product> GetProducts(IList<int> productCategoryIds, IList<int> tagIds, IList<int> memberTypeIds, int maxItems, int pageNumber, out PagingInfo pagingInfo, Enums.SortBy sortBy, Decimal? priceLower, Decimal? priceUpper, Int32? manufacturerId, Boolean loadVariations = false, Boolean viewAll = false, Boolean loadNotDirectlyPurchasable = false, Boolean loadPriceMatrices = false)
{
var memberType = MemberType.Retail;
if (memberTypeIds.HasItemsAndNotNull())
memberType = (MemberType)memberTypeIds.FirstOrDefault();
if (pageNumber <= 0)
pageNumber = 1;
var start = maxItems * (pageNumber - 1);
var searchProvider = ExamineManager.Instance.SearchProviderCollection[ProductIndexProviderName];
var criteria = ExamineManager.Instance.SearchProviderCollection[ProductIndexProviderName].CreateSearchCriteria();
var helper = new UmbracoHelper(UmbContext);
var query = String.Format("+nodeTypeAlias:{0} AND +search_memberTypeIds:({1})", "Product", String.Join(" ", memberTypeIds));
if (productCategoryIds.HasItemsAndNotNull())
query += String.Format(" AND +search_productCategoryIds:({0})", String.Join(" ", productCategoryIds));
if (tagIds.HasItemsAndNotNull())
query += String.Format(" AND +search_tagIds:({0})", String.Join(" ", tagIds));
if (manufacturerId.HasValue)
query += String.Format(" AND +ManufacturerId:({0})", manufacturerId.Value);
var priceField = "search_retailPrice";
switch (memberType)
{
case MemberType.Government:
priceField = "search_governmentPrice";
break;
case MemberType.DropShip:
priceField = "search_dropShipPrice";
break;
case MemberType.Trade:
priceField = "search_tradePrice";
break;
case MemberType.Wholesale:
priceField = "search_wholesalePrice";
break;
}
// Narrow down by not directly purchasable
if (!loadNotDirectlyPurchasable)
query += " AND +search_notDirectlyPurchasable:0";
// We use D20 as we want to pad the int (after converting from decimal) to properly query
// a range in Examine (Lucene)
if (priceLower.HasValue && priceUpper.HasValue)
{
var lower = Convert.ToInt64(priceLower.Value).ToString("D20");
var upper = Convert.ToInt64(priceUpper.Value).ToString("D20");
query += String.Format(" AND +{0}:[{1} TO {2}]", priceField, lower, upper);
}
else
{
// Narrow down by price (lower)
if (priceLower.HasValue)
{
var lower = Convert.ToInt64(priceLower.Value).ToString("D20");
var upper = new String('9', 20);
query += String.Format(" AND +{0}:[{1} TO {2}]", priceField, lower, upper);
}
// Narrow down by price (upper)
if (priceUpper.HasValue)
{
var lower = 0.ToString("D20");
var upper = Convert.ToInt64(priceUpper.Value).ToString("D20");
query += String.Format(" AND +{0}:[{1} TO {2}]", priceField, lower, upper);
}
}
criteria.RawQuery(query);
// Sort
if (sortBy == Enums.SortBy.HighestRated)
criteria.OrderByDescending(new[] {"AverageRating"});
else if (sortBy == Enums.SortBy.BestSelling)
criteria.OrderByDescending(new[] { "TotalSold" });
else if (sortBy == Enums.SortBy.PriceLowToHigh)
criteria.OrderBy(new[] { priceField });
else if (sortBy == Enums.SortBy.PriceHighToLow)
criteria.OrderByDescending(new[] { priceField });
// Paginate
IList<Product> results;
IList<SearchResult> searchResults;
if (!viewAll)
{
var total = searchProvider.Search(criteria).Count();
// Now do again to get paginated results
searchResults = searchProvider.Search(criteria).Skip(start).Take(maxItems).ToList();
results = helper.TypedContent(searchResults.Select(x => x.Id)).ConvertToTypedList<Product>();
pagingInfo = PagingHelpers.GetPagingInfo(total, maxItems, pageNumber);
}
else
{
var total = searchProvider.Search(criteria).Count();
searchResults = searchProvider.Search(criteria).ToList();
results = helper.TypedContent(searchResults.Select(x => x.Id)).ConvertToTypedList<Product>();
pagingInfo = PagingHelpers.GetPagingInfo(total);
}
if (loadVariations && results.HasItemsAndNotNull())
{
var tmpProductIds = results.Select(x => x.Id).ToList();
var variations = _productVariationRepository.GetByProductIds(tmpProductIds);
if (variations.HasItemsAndNotNull())
{
foreach (var result in results)
{
result.ProductVariations = variations.Where(x => x.ParentId == result.Id).ToList();
}
}
}
if (loadPriceMatrices && results.HasItemsAndNotNull())
{
foreach (var result in results)
{
var searchResult = searchResults.FirstOrDefault(x => x.Id == result.Id);
result.PriceMatrix = new PriceRangeMatrix()
{
MinRetailPrice = searchResult.GetDecimalValueSafelyByKey("search_min_retailPrice"),
MaxRetailPrice = searchResult.GetDecimalValueSafelyByKey("search_max_retailPrice"),
MinDropshipPrice = searchResult.GetDecimalValueSafelyByKey("search_min_dropShipPrice"),
MaxDropshipPrice = searchResult.GetDecimalValueSafelyByKey("search_max_dropShipPrice"),
MinGovernmentPrice = searchResult.GetDecimalValueSafelyByKey("search_min_governmentPrice"),
MaxGovernmentPrice = searchResult.GetDecimalValueSafelyByKey("search_max_governmentPrice"),
MinTradePrice = searchResult.GetDecimalValueSafelyByKey("search_min_tradePrice"),
MaxTradePrice = searchResult.GetDecimalValueSafelyByKey("search_max_tradePrice"),
MinWholesalePrice = searchResult.GetDecimalValueSafelyByKey("search_min_wholesalePrice"),
MaxWholesalePrice = searchResult.GetDecimalValueSafelyByKey("search_max_wholesalePrice"),
};
}
}
return results;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment