Don't miss out Virtual Happy Hour this Friday (April 26).

Try our conversational search powered by Generative AI!

Updating Episerver Find index with custom field values from related entities

Vote:
 

Hi,

I have setup a catalog search using a Product entity and related Segment entities. So each product can have multiple Segments associated with it. The segment entitiy has a property called Applications that holds a list of string values and some other properties not relevant to this question. In order to search for Products based on the Segment.Applicaitons values I have added a computed property to Product that holds all values of the Applications property of all it's related Segments. So this is just an array of all string values of the related Segment.Applications field. The Product.Applications property just iterates over all related Segments and build a new array of the Segment.Applications. This is then added to the find index. And searching for a value from one of the applications arrayof a segment reults in a list of products as expected. so far so good. 

the search fnctionality is pretty strait forward. search for a string, get a list of products as a result, click on a produc to open the Preoduct Details Page that will show all properties and associated Segment information.

the Product.Applications property looks like this:

[Searchable]
[Tokenize]
public IEnumerable Applications => this.GetApplications()

...

 public static IEnumerable GetApplications(this IContent content)
{
List result = new List();

var associations = AssociationsRepository.Service.GetAssociations(content.ContentLink);

foreach (var association in associations)
{
if (association.Target.Get() is Segment a)
{
result.AddRange(a.Application);
}
}

return result.Distinct();
}

So the issue if have is in updating the find index. Iwould expect that wen I change the value of the Segment.Applications, this will reflect on the Product.Applications value in the Episerver Find Index. This does not happen. Only when I run the  EPiServer Find Content Indexing Job the Product.Applications values are updated with the correct values.

My question is: Is there a way to update the Product.Applications values when the Segment.Applications is changed immediately and without running the EPiServer Find Content Indexing Job every time?

One thing to note is that the catalog is imported using the episerver xml import. and I tried to setup a convenition on the Product.Applicaitons field, but that diddn't help. something like:

ForInstancesOf().IncludeField(x => x.Applications);

thnx

Pierre

#192046
May 04, 2018 8:37
Vote:
 

We had a similar issue with a solution we were building. We had some venue models that had a list of courses that referenced that venue. When indexing the list would update with what courses were at that venue. However, when we updated any of the courses, the list did not update.

To get around this we have an event initializable module that hooks into the publish event and checks to see if the item being published is one of the types that needs to update the referenced courses. If it is it will work out what model needed to be updated by getting the content reference (or list of them) and force a re-index of the venue.

Here is an example:

private void FindEventIndex(ContentEventArgs e)
{
    var itemType = e.Content.GetOriginalType();
    var basePageMatchType = new[]
    {
        typeof(CourseBaseProduct),
        typeof(CourseVenueProduct),
        typeof(CourseScheduleVariant)
    };

    if (itemType.InheritsAnyClass(basePageMatchType))
    {
        var contentRepository = ServiceLocator.Current.GetInstance<IContentLoader>();
        var content = contentRepository.Get<IContent>(e.ContentLink);
        Task.Run(() => CourseReindexingService.Service.ReindexReleatedVenues(content));
    }
}

Then this will run a service that will update the venue in the index using the following code:

public async Task ReindexReleatedVenues(IContent contentObject)
{
    var itemType = contentObject.GetOriginalType();

    if (itemType == typeof(CourseScheduleVariant))
    {
        try
        {
            var courseScheduleVariant = ContentLoaderService.Service.Get<CourseScheduleVariant>
                (contentObject.ContentLink);

            if (!ContentReference.IsNullOrEmpty(courseScheduleVariant.ParentCourseVenueProduct.Venue))
            {
                var relatedVenue = ContentLoaderService.Service.Get<VenueContentItem>
                    (courseScheduleVariant.ParentCourseVenueProduct.Venue);

                if (relatedVenue != null)
                {
                    FindClientService.Service.Index(relatedVenue);
                }
            }
        }
        catch (Exception ex)
        {
            LoggerService.Service.Log(Level.Error, "Failed to index a single venue from a schedule variant.", ex);
        }
    }
}

I don't know if this is something that you would want to do but this is the way we got around the issue. It does mean that it will re-index the specified item in the index and the information will be up to date though

#192057
May 04, 2018 11:34
Vote:
 

Hi Steve,

Thanks for your info. I will check if this can work for me. Acting on the publish event is a good idea anyway.

I'm not sure if the model I'm using allows me to retrieve the products related to a segment yet, but I guess I will find out :)

I'll let you know the outcome.

Thnx,

Pierre 

#192102
May 07, 2018 14:58
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.