public IHttpActionResult Search(string store, string[] priceLists, [ModelBinder(typeof(SearchParametersBinder))] SearchParameters parameters, [FromUri] coreModel.ItemResponseGroup responseGroup = coreModel.ItemResponseGroup.ItemMedium, [FromUri] string outline = "", string language = "en-us", string currency = "USD") { var context = new Dictionary <string, object> { { "StoreId", store }, }; var fullLoadedStore = GetStoreById(store); if (fullLoadedStore == null) { throw new NullReferenceException(store + " not found"); } var catalog = fullLoadedStore.Catalog; string categoryId = null; var criteria = new CatalogIndexedSearchCriteria { Locale = language, Catalog = catalog.ToLowerInvariant() }; if (!string.IsNullOrWhiteSpace(outline)) { criteria.Outlines.Add(String.Format("{0}/{1}*", catalog, outline)); categoryId = outline.Split(new[] { '/' }).Last(); context.Add("CategoryId", categoryId); } #region Filters // Now fill in filters var filters = _browseFilterService.GetFilters(context); // Add all filters foreach (var filter in filters) { criteria.Add(filter); } // apply terms if (parameters.Terms != null && parameters.Terms.Count > 0) { foreach (var term in parameters.Terms) { var filter = filters.SingleOrDefault(x => x.Key.Equals(term.Key, StringComparison.OrdinalIgnoreCase) && (!(x is PriceRangeFilter) || ((PriceRangeFilter)x).Currency.Equals(currency, StringComparison.OrdinalIgnoreCase))); var appliedFilter = _browseFilterService.Convert(filter, term.Value); criteria.Apply(appliedFilter); } } #endregion #region Facets // apply facet filters var facets = parameters.Facets; if (facets.Count != 0) { foreach (var key in facets.Select(f => f.Key)) { var filter = filters.SingleOrDefault( x => x.Key.Equals(key, StringComparison.OrdinalIgnoreCase) && (!(x is PriceRangeFilter) || ((PriceRangeFilter)x).Currency.Equals(currency, StringComparison.OrdinalIgnoreCase))); var appliedFilter = _browseFilterService.Convert(filter, facets.FirstOrDefault(f => f.Key == key).Value); criteria.Apply(appliedFilter); } } #endregion //criteria.ClassTypes.Add("Product"); criteria.RecordsToRetrieve = parameters.PageSize == 0 ? 10 : parameters.PageSize; criteria.StartingRecord = parameters.StartingRecord; criteria.Pricelists = priceLists; criteria.Currency = currency; criteria.StartDateFrom = parameters.StartDateFrom; criteria.SearchPhrase = parameters.FreeSearch; #region sorting if (!string.IsNullOrEmpty(parameters.Sort)) { var isDescending = "desc".Equals(parameters.SortOrder, StringComparison.OrdinalIgnoreCase); SearchSort sortObject = null; switch (parameters.Sort.ToLowerInvariant()) { case "price": if (criteria.Pricelists != null) { sortObject = new SearchSort( criteria.Pricelists.Select( priceList => new SearchSortField(String.Format("price_{0}_{1}", criteria.Currency.ToLower(), priceList.ToLower())) { IgnoredUnmapped = true, IsDescending = isDescending, DataType = SearchSortField.DOUBLE }) .ToArray()); } break; case "position": sortObject = new SearchSort( new SearchSortField(string.Format("sort{0}{1}", catalog, categoryId).ToLower()) { IgnoredUnmapped = true, IsDescending = isDescending }); break; case "name": sortObject = new SearchSort("name", isDescending); break; case "rating": sortObject = new SearchSort(criteria.ReviewsAverageField, isDescending); break; case "reviews": sortObject = new SearchSort(criteria.ReviewsTotalField, isDescending); break; default: sortObject = CatalogIndexedSearchCriteria.DefaultSortOrder; break; } criteria.Sort = sortObject; } #endregion //Load ALL products var searchResults = _browseService.SearchItems(criteria, responseGroup); // populate inventory if ((responseGroup & ItemResponseGroup.ItemProperties) == ItemResponseGroup.ItemProperties) { PopulateInventory(fullLoadedStore.FulfillmentCenter, searchResults.Items); } return(this.Ok(searchResults)); }
public IHttpActionResult Search([FromUri] ProductSearchRequest request) { request = request ?? new ProductSearchRequest(); request.Normalize(); var context = new Dictionary <string, object> { { "StoreId", request.Store }, }; var fullLoadedStore = GetStoreById(request.Store); if (fullLoadedStore == null) { throw new NullReferenceException(request.Store + " not found"); } var catalog = fullLoadedStore.Catalog; string categoryId = null; var criteria = new CatalogIndexedSearchCriteria { Locale = request.Language, Catalog = catalog.ToLowerInvariant(), IsFuzzySearch = true }; if (!string.IsNullOrWhiteSpace(request.Outline)) { criteria.Outlines.Add(string.Format("{0}/{1}*", catalog, request.Outline)); categoryId = request.Outline.Split(new[] { '/' }).Last(); context.Add("CategoryId", categoryId); } #region Filters // Now fill in filters var filters = _browseFilterService.GetFilters(context); // Add all filters foreach (var filter in filters) { criteria.Add(filter); } // apply terms var terms = ParseKeyValues(request.Terms); if (terms.Any()) { var filtersWithValues = filters .Where(x => (!(x is PriceRangeFilter) || ((PriceRangeFilter)x).Currency.Equals(request.Currency, StringComparison.OrdinalIgnoreCase))) .Select(x => new { Filter = x, Values = x.GetValues() }) .ToList(); foreach (var term in terms) { var filter = filters.SingleOrDefault(x => x.Key.Equals(term.Key, StringComparison.OrdinalIgnoreCase) && (!(x is PriceRangeFilter) || ((PriceRangeFilter)x).Currency.Equals(request.Currency, StringComparison.OrdinalIgnoreCase))); // handle special filter term with a key = "tags", it contains just values and we need to determine which filter to use if (filter == null && term.Key == "tags") { foreach (var termValue in term.Values) { // try to find filter by value var foundFilter = filtersWithValues.FirstOrDefault(x => x.Values.Any(y => y.Id.Equals(termValue))); if (foundFilter != null) { filter = foundFilter.Filter; var appliedFilter = _browseFilterService.Convert(filter, term.Values); criteria.Apply(appliedFilter); } } } else { var appliedFilter = _browseFilterService.Convert(filter, term.Values); criteria.Apply(appliedFilter); } } } #endregion #region Facets // apply facet filters var facets = ParseKeyValues(request.Facets); foreach (var facet in facets) { var filter = filters.SingleOrDefault( x => x.Key.Equals(facet.Key, StringComparison.OrdinalIgnoreCase) && (!(x is PriceRangeFilter) || ((PriceRangeFilter)x).Currency.Equals(request.Currency, StringComparison.OrdinalIgnoreCase))); var appliedFilter = _browseFilterService.Convert(filter, facet.Values); criteria.Apply(appliedFilter); } #endregion //criteria.ClassTypes.Add("Product"); criteria.RecordsToRetrieve = request.Take <= 0 ? 10 : request.Take; criteria.StartingRecord = request.Skip; criteria.Pricelists = request.Pricelists; criteria.Currency = request.Currency; criteria.StartDateFrom = request.StartDateFrom; criteria.SearchPhrase = request.SearchPhrase; #region sorting if (!string.IsNullOrEmpty(request.Sort)) { var isDescending = "desc".Equals(request.SortOrder, StringComparison.OrdinalIgnoreCase); SearchSort sortObject = null; switch (request.Sort.ToLowerInvariant()) { case "price": if (criteria.Pricelists != null) { sortObject = new SearchSort( criteria.Pricelists.Select( priceList => new SearchSortField(String.Format("price_{0}_{1}", criteria.Currency.ToLower(), priceList.ToLower())) { IgnoredUnmapped = true, IsDescending = isDescending, DataType = SearchSortField.DOUBLE }) .ToArray()); } break; case "position": sortObject = new SearchSort( new SearchSortField(string.Format("sort{0}{1}", catalog, categoryId).ToLower()) { IgnoredUnmapped = true, IsDescending = isDescending }); break; case "name": sortObject = new SearchSort("name", isDescending); break; case "rating": sortObject = new SearchSort(criteria.ReviewsAverageField, isDescending); break; case "reviews": sortObject = new SearchSort(criteria.ReviewsTotalField, isDescending); break; default: sortObject = CatalogIndexedSearchCriteria.DefaultSortOrder; break; } criteria.Sort = sortObject; } #endregion //Load ALL products var searchResults = _browseService.SearchItems(criteria, request.ResponseGroup); // populate inventory if ((request.ResponseGroup & ItemResponseGroup.ItemProperties) == ItemResponseGroup.ItemProperties) { PopulateInventory(fullLoadedStore.FulfillmentCenter, searchResults.Items); } return(Ok(searchResults)); }