Steven Galton
Jan 2, 2018
  1962
(3 votes)

Indexing extra Episerver Find properties onto a single variant for Episerver Commerce

Recently on a client project that I have been working on at Redweb, I have been working on getting Episerver Find working with Episerver Commerce. This was a simple task as you just needed to do some configuration and run the index job in the Commerce manager (Guide found here). 

The main issue that arose was that the catalogue structure was very complicated, and information was split across difference parents and children. This made it a bit difficult to get all the information needed for a single variant. Rather than doing multiple searches, I found that you could simply index this information into a single variant. 

To get the information to index onto the single variant, I created some properties that are ignored by the CMS. These would be used to store the actual information needed from the different parents of the variant.

[Ignore]
public string LocationName => SearchLocationName();

[Ignore]
public string Title => SearchTitleText();

[Ignore]
public string Description => SearchDescriptionText();

[Ignore]
public bool IsWeekendCourse => CourseRunType.HasFlag(CourseRunType.Weekend);

[Ignore]
public bool IsWeekdayCourse => CourseRunType.HasFlag(CourseRunType.Weekday);

Some more properties were added that would store a reference to the parents of the variant that were also hidden from the CMS. Some methods were created that would then extract the information from these properties and then assign them to the properties created above.

private CourseVenueProduct _parentCourseVenueProduct;
private CourseProduct _parentCourseProduct;
private CourseCategory _parentCourseCategory;
private CourseRunType ? _courseRunType;

[Ignore]
public CourseVenueProduct ParentCourseVenueProduct 
{
    get 
    {
        if (_parentCourseVenueProduct == null) 
        {
            var parentProduct = this.GetParentProducts().FirstOrDefault();
            var loader = ServiceLocator.Current.GetInstance<IContentLoader>();
            _parentCourseVenueProduct = loader.Get<CourseVenueProduct>(parentProduct);
        }
        
        return _parentCourseVenueProduct;
    }
}

[Ignore]
public CourseProduct ParentCourseProduct 
{
    get 
    {
        if (_parentCourseProduct == null) 
        {
            var parentCourseProduct = this.ParentLink;
            var loader = ServiceLocator.Current.GetInstance<IContentLoader>();
            _parentCourseProduct = loader.Get<CourseProduct>(parentCourseProduct);
        }
    
        return _parentCourseProduct;
    }
}

[Ignore]
public CourseCategory ParentCourseCategory 
{
    get 
    {
        if (_parentCourseCategory == null) 
        {
            var parentCourseCategory = ParentCourseProduct.ParentLink;
            var loader = ServiceLocator.Current.GetInstance<ContentLoader>();
            _parentCourseCategory = loader.Get<CourseCategory> (parentCourseCategory);
        }
        
        return _parentCourseCategory;
    }
}

[Ignore]
public CourseRunType CourseRunType 
{
    get 
    {
        if (_courseRunType == null) 
        {
            var workingDaysService = ServiceLocator.Current.GetInstance<IWorkingDays>();
            _courseRunType = workingDaysService.GetCourseRunType(CourseStartDate, CourseEndDate);
        }
    
        return _courseRunType.Value;
    }
}

private string SearchLocationName() 
{
    return ParentCourseVenueProduct.DisplayName;
}

private string SearchTitleText() 
{
    return ParentCourseCategory.DisplayName;
}

private string SearchDescriptionText() 
{
    return ParentCourseProduct.DisplayName;
}

When a new item was created, updated or the indexing job was run, the new properties would be updated and indexed so they could be used to filter against in the search queries. There was also an added benefit as you could also use these properties elsewhere in the solution.

Image Capture.PNG

[Pasting files is not allowed][Pasting files is not allowed]

Jan 02, 2018

Comments

Jeroen Stemerdink
Jeroen Stemerdink Jan 2, 2018 09:57 AM

I am not a big fan of adding properties with a lot of logic to your models, especially when it is only needed for your search index.

Have a ook at this thread, which is IMHO a much cleaner approach., and works just as well.

Steven Galton
Steven Galton Jan 2, 2018 10:11 AM

We used the convention way to add the properties to our search index before but realised that we needed to use the properties in other methods. We will be looking to move the logic into their own helpers in the future as well.

Please login to comment.
Latest blogs
Optimizely For you Intranet

Having been at Optimizely and in the CMS industry for nearly 16 years I have seen clients’ intranet requirements go from a simple site just to hous...

Robert Folan | Sep 22, 2023

Vulnerability in EPiServer.GoogleAnalytics v3 and v4

Introduction A potential security vulnerability was detected for Optimizely Google Analytics addon (including EPiServer.GoogleAnalytics and...

Bien Nguyen | Sep 20, 2023

Overriding Optimizely’s Content Recommendations Block to Implement Custom Recommendations

Introduction The Content Recommendations add-on for Optimizely CMS dynamically recommends content from your site tailored to the interests of each...

abritt | Sep 13, 2023 | Syndicated blog

Developer contest! Install the AI Assistant and Win Bose QC45 Headphones!

We are thrilled to announce a developer contest where you have the chance to win a pair of Bose Headphones. The goal is to be the first developer t...

Luc Gosso (MVP) | Sep 7, 2023 | Syndicated blog

Send Optimizely notifications with SendGrid API, not SMTP

If your Optimizely site already sends transaction emails through an email platform API, why not do the same with Optimizely notification emails?

Stefan Holm Olsen | Sep 6, 2023 | Syndicated blog

Optimizely Configured Commerce Custom POST API

Introduction When creating custom API controllers for an Optimizely B2B project it’s possible you’ll want to create POST calls. Following the...

Dylan Barter | Sep 6, 2023