Documentation

Ucommerce includes full API reference documentation and lots of helpful articles to help you build your e-commerce site as effortlessly as possible.

Topics Payment Providers
v7.18

Add custom data to index

In 9.4, we introduced the interface Ucommerce.Search.IAdorn that will allow you to add custom data to your index.

If your custom data is already in a definition field, this article is not for you. Please just add that property to your custom index definition.

One thing to mention, you can not store nested data structures. For example, you can not store a List of product relations, each with its own List of products.

Below is the interface. It has 2 methods for adding data to the index. One is for generic product properties, the second is used for language specific properties.

Ucommerce.Search.IAdorn`1

Description

When indexing Ts, provides a hook to transform, filter or amend the items going into the index. The Ts passed to Adorn have been localized, so any adornments must take this into account, adding data localized for each CultureInfo.

Methods


Adorn

  • Arguments
    • IEnumerable<Ucommerce.Search.T> items
  • Return type Void

Adorn

  • Arguments
    • IEnumerable<Ucommerce.Search.T> localizedItems
    • CultureInfo culture
  • Return type Void

As one of the most requested usages of the index, I will add product relations to the product index. By default, the index has a list of all related products but that list does not take into consideration the type of relationship.

Below we will index product relationships and their types. Since the index will only allow storing of simple values, we index each relation by its type and save the GUID for the product rather than the product itself. That keeps the index size down while allowing us to query for the product.

Here is a code example:

    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    
    namespace UcommerceCodeSamples.IndexAndSearch
    {
        public class AddingCustomIndex
        {
            public class ProductRelationsAdorner : Ucommerce.Search.IAdorn<Ucommerce.Search.Models.Product>
            {
                
                // Getting a product relation repository
                [Ucommerce.Infrastructure.Components.Windsor.Mandatory] private Ucommerce.EntitiesV2.IRepository<Ucommerce.EntitiesV2.ProductRelation> ProductRelationRepository  { get; set; }
                public void Adorn(IEnumerable<Ucommerce.Search.Models.Product> products)
                {
                    foreach (Ucommerce.Search.Models.Product product in products)
                    {
                        //collecting all the related products
                        var relatedProducts = ProductRelationRepository.Select().Where(x => product.RelatedProducts.Contains(x.RelatedProduct.Guid ) && x.Product.Guid == product.Guid);
                        //grouping them by type
                        var relatedProductsGroupedByName =  relatedProducts.ToLookup(x => x.ProductRelationType.Name, x => x.RelatedProduct.Guid);
    
                        //adding the data to our index model. At this point the model has the data, but you still need to map it to your index.
                        foreach (var productRelationType in relatedProductsGroupedByName)
                        {
                            product[productRelationType.Key] = productRelationType.ToList();
                        }
                    }
                }
                public void Adorn(IEnumerable<Ucommerce.Search.Models.Product> localizedProducts, CultureInfo culture)
                {
                    
                }
            }
            
        }
    }

Below is how you register the component. Read more about registering components here

    
    <components>
    <component id="ProductRelationsAdorner"
                       service="Ucommerce.Search.IAdorn`1[[Ucommerce.Search.Models.Product, Ucommerce.Search]], Ucommerce.Search"
                       type="your_namespace.your_class, your_dll" />
    </components>
    

​ And adding the field to the index definition:

    this.Field(p => p["relation_name"]);
    

Please remember to restart of the website for the component to be registered and run the scratch indexer to populate the data of your index.