November Happy Hour will be moved to Thursday December 5th.

Product/Variation Search Approach

Vote:
 

We are using Commerce 12 with Find.  However, my question is less technical and more about best practices.

I'm struggling a little bit with the proper approach to searching a catalog.  Our catalog has a fairly straightforward structure in which our products have high level properties (brand, flavor, texture) and our variants have container information (container type, size) that act as our SKUs.  

The search results we would like to return are not products.  We really want just the variants to show up in a product search.  While I can do this by specifying the ClassType in the criteria object, we lose facets at the product level (such as brand).

As a general approach, what is the proper way to tackle a scenario like this?  Do we have to do custom indexing or is there a more straightforward approach we could take?  If we index, should we be adding product information to our variant entries or vise-versa?

#204469
Edited, Jun 03, 2019 21:02
Vote:
 

I'm not sure I see the whole picture, but do you support searching by container information (i.e. SKU information), or only high level properties?

#204515
Jun 04, 2019 22:36
Vote:
 

Easiest way would be to use an extension method to add container type and size to the products.  It can just be a unique select on varitions size and variations container.  The result would be IEumerable<string>

SearchClient.Instance.Conventions.ForInstancesOf<ProductContent>().IncludeField(_ => _.Sizes());

SearchClient.Instance.Conventions.ForInstancesOf<ProductContent>().IncludeField(_ => _.Containers());

public static class ProductContentExtensions
{
    private static readonly Lazy<IRelationRepository> RelationRepository = new Lazy<IRelationRepository>(() => ServiceLocator.Current.GetInstance<IRelationRepository>());
    private static readonly Lazy<IContentLoader> ContentLoader = new Lazy<IContentLoader>(() => ServiceLocator.Current.GetInstance<IContentLoader>());

    public static IEnumerable<string> Sizes(this EntryContentBase productContent)
    {
        return productContent.VariationContents()
            .Select(_ => _.Size);
    }

    public static IEnumerable<string> Containers(this EntryContentBase productContent)
    {
        return productContent.VariationContents()
            .Select(_ => _.Container);
    }    

    public static IEnumerable<VariationContent> VariationContents(this ProductContent productContent)
    {
    return ContentLoader.Value.GetItems(productContent.GetVariants(RelationRepository.Value), productContent.Language).OfType<VariationContent>();
    }

}
#204519
Jun 05, 2019 4:09
Vote:
 

Thanks Mark.  I'm going to give this a shot this morning and see if this solves my issue.  Since we actually want the search results to be SKUs in our case, I suspect I will want to use the same approach but on variants instead.  Either way I can follow what you are suggesting.

Quan, we do support searching by SKU information.  Our site has an auto-complete search that targets products as well as a more comprehensive search page that returns SKUs and makes use of facets.  It was this second search that was giving me issues because the facets are tied to product properties that were not included in the index for SKU items.

#204536
Jun 05, 2019 15:22
Vote:
 

Then I second Mark's suggestion

#204537
Jun 05, 2019 15:34
Vote:
 

To close this one out, we followed Mark's suggestion and only altered it slightly to get product properties indexed within the SKU items.  

To do this we added a method to retrieve the first parent product item as we always have just a single parent associated with a SKU.

public static ProductContent ParentProduct(this VariationContent variationContent)
{
     var productContents = ContentLoader.Value
         .GetItems(variationContent.GetParentProducts(RelationRepository.Value), variationContent.Language)
         .OfType<ProductContent>().ToList();
            
     return productContents.Any() ? productContents.First() : null;
}

Then used this method in the individual property extensions like so:

public static string Brand(this VariationContent variationContent)
{
     return variationContent.ParentProduct().GetValue("Brand").ToString();
}

Works like a charm - Thanks!

#204800
Edited, Jun 18, 2019 17:08
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* 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.