Custom Data

Add custom or external data to your index.

This article is not relevant if your custom data is already in a definition field. Instead, you can simply add the property to your custom index definition.

If you wish to add custom or external data to your index, Ucommerce provides the interface IAdorn<T> where T is the search model type, e.g. ProductSearchModel. The interface provides 2 methods, one for general properties and one for language-specific (multilingual) properties:

General properties
Task<IImmutableList<T>> Adorn(
            IImmutableList<T> items,
            DeserializedDataBase<T> rawData,
            CancellationToken token);
Language-specific properties
Task<ImmutableDictionary<CultureInfo, IImmutableList<T>>> Adorn(
            ImmutableDictionary<CultureInfo, IImmutableList<T>> items,
            DeserializedDataBase<T> rawData,
            CancellationToken token);

In many cases it's only necessary to implement one of the two methods of the interface to add the desired data. When this happens, simply return the items parameter using return await items.InTask();in the other method.

Below is an example of an adorner that adds the product id to the product index.

public class ProductIdAdorner : IAdorn<ProductSearchModel>
    {
        private readonly UcommerceDbContext _dbContext;

        /// <summary>
        /// Constructor
        /// </summary>
        public ProductIdAdorner(UcommerceDbContext dbContext)
        {
            _dbContext = dbContext;
        }
        
        /// <inheritdoc />
        public virtual async Task<IImmutableList<ProductSearchModel>> Adorn(
            IImmutableList<ProductSearchModel> items,
            DeserializedDataBase<ProductSearchModel> rawData,
            CancellationToken token)
        {
            foreach (var productSearchModel in items)
            {
                var productEntity = await _dbContext.Products.FirstAsync(p => p.Guid == productSearchModel.Id, token);
                productSearchModel["LegacyId"] = productEntity.Id;
            }

            return items;
        }

        /// <inheritdoc />
        public virtual Task<ImmutableDictionary<CultureInfo, IImmutableList<ProductSearchModel>>> Adorn(
            ImmutableDictionary<CultureInfo, IImmutableList<ProductSearchModel>> items,
            DeserializedDataBase<ProductSearchModel> rawData,
            CancellationToken token) =>
            items.InTask();
    }

To register your adorner, add it to the service collection like this:

builder.Services.AddScoped<IAdorn<ProductSearchModel>, ProductIdAdorner>();

Use AddScoped instead of AddSingleton if the adorner depends on any scoped instances, e.g. UcommerceDbContext like above. Microsoft Dependency Injection framework will let you know if you forget by throwing an exception on startup.

Remember to check that the property is part of the index definition, otherwise add it:

this.Field(p => p["LegacyId"], typeof(int));

Last updated

Was this helpful?