Try our conversational search powered by Generative AI!

Filter articles but showing products


We have had this up with EPiServer but haven't come any close to a solution.

What we want to achieve is to have a product listing, with paging and with the ability to filter based on the articles/variants data but showing the product in the listing. As it works now the article/variant has for instance a color meta data and for this filter to be visible we have to fetch the articles/variants. If switching to products in the listings the filter disappears because the meta field is not existing on the product.

For the customer we want to present the product and have the color as a quickselector, but the customer must be able to filter the listing based on color.

Is there anyone hwo have had the same requirements and have solved this in any manner?

Apr 29, 2013 11:23

We did have similar requirements for one of our clients. Each product has so called main product and also may have multiple variations - together refered as family. This is common for paint SKUs for instance - base color and default volume and then - different bases, different volumes - 3L, 5L, etc.

What we did was to index all the main and variation products in EPiServer.Find. We were showing only main products on prodct grid but at the sime time we had to show also filtering criteria so called "facets". Filtering criteria was based on all possible base color and volume combinations - so end user could pick up necessary combination. This was done using special Find query to fetch all hits with that particular category and then calculated possible filter criterias for products that matched category. Results were cached just for some performance gains.

Hope this helps!

Apr 29, 2013 15:35

Entries entries = new Entries();

// Perform Lucene search
SearchResults results = searchFilterHelper.SearchEntries(criteria,false,0) as SearchResults;

// Get IDs we need
int[] resultIndexes = results.GetIntResults(pageNumber , maxRows+5); // we add padding here to accomodate entries that might have been deleted since last indexing

if (resultIndexes.Length > 0)
int[] productResultIndexes = RefinementHelper.GetParentProducts(pageSize, pageNumber, resultIndexes, ref totalRows);

// Retrieve actual entry objects, with no caching
entries = CatalogContext.Current.GetCatalogEntries(productResultIndexes, false, new TimeSpan(), responseGroup);

// Add in attribute information
AddAttributes(entries, results);

// Insert to the cache collection
entries.TotalResults = totalRows;
CatalogCache.Insert(cacheKey, entries, cacheTimeout);


Where RefinementHelper.GetParentProducts is a custom function that retrive Unique Product Ids for variants using a stored procedure.

May 02, 2013 13:02

Ok trying this code out but can't resolve the RefinementHelper. In which assembly does it exists? We are using Commerce R2 SP2.

May 06, 2013 8:52

Hi Tobias,


RefinementHelper.GetParentProducts is a custom In-house build function that retrive Unique Product Ids for variants using a stored procedure.
You need to retrive Parent product ids of selected variants first.



May 07, 2013 10:18

Ok misunderstood that. I get the concept so will try an approach on this.

May 07, 2013 10:29

Khan, how does your example code above handle paging and filter count? We are discussing how to solve this in a good way that uses the standard functionality in Commerce but struggles a bit at how to get the variants to fill a page of 20 products since it differs how many articles are part of same product.

May 07, 2013 12:42

You can cache the results for your categories with a unique key. e.g.

cacheKey = CatalogCache.CreateCacheKey("your-products", responseGroup.CacheKey, criteria.CacheKey, string.Format("maxRows:{0}pageNumber:{1}pageSize:{2}", maxRows.ToString(), pageNumber.ToString(), pageSize.ToString()));

For Search result you may not like to cache that.

Filter Count is an issue, we agreed with client that we will not show counts as it is useless for him and will effect performance.

May 07, 2013 12:56

We have managed to get to some kind of a solution but not certain if there are any aspect of it that is a bad way to do it.

After trying some different ways to accomplish this and looking at the performance of the different methods we now use a solution like this:

First all variations get a custom field that holds the parent product CatalogEntryId. This is done in a custom import procedure we have.

Then on the productlisting page we get ALL the variations in a given catalogNode and with applied filters. For this we use a criteria that has a recordsToRetrieve to a high value to be sure to get all. We then search these entries like this:

var entries = _searchFilterHelper.SearchEntries(criteria, new CatalogEntryResponseGroup(CatalogEntryResponseGroup.ResponseGroup.CatalogEntryInfo), false, new TimeSpan());

These entries are then looped through and all unique parent product catalogEntryId are put in a int array which is the used to get the ProductEntries:

var products = CatalogContext.Current.GetCatalogEntries(productsList.ToArray(), false, new TimeSpan(), new CatalogEntryResponseGroup(CatalogEntryResponseGroup.ResponseGroup.CatalogEntryInfo));

All hese products are then cached with a cachekey that has the catalogNodeCode and mapped filters.

Then from this list of products we get a subset according to the current paging and items per page settings. This meams that for each paging request we can read from the whole cached product result and just get the correct items.

When looking at the performance we are trying this on a catalog node with 740 variations and 170 products the uncached result is recieved in about 1 second and cached its just about 100 ms for the page to load.

But does anyone see any problems with this approach?

May 10, 2013 12:42

You may need to consider the Cache Timeout factor also. You can introduce expiry level and can reset through config according clients requiremnt. As he may would like to see his products as soon as he uploads his products in XMas season.

Edited, May 10, 2013 12:47
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.