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> which provides you with 2 methods:

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

You cannot store nested data structures; for instance, you cannot store a list of product relationships, each with its list of products. If you require such flexibility, you will need to create your own search model.

Below is an example of an adorner that adds product relations to the product index:

This adorner is already built into Ucommerce.

public class ProductRelatedProductAdorner : IAdorn<ProductSearchModel>
    {
        /// <inheritdoc />
        public virtual async Task<IImmutableList<ProductSearchModel>> Adorn(
            IImmutableList<ProductSearchModel> items,
            DeserializedDataBase<ProductSearchModel> rawData,
            CancellationToken token)
        {
            if (rawData is not ProductDeserializeData data)
            {
                return await items.InTask();
            }

            items = AdornRelatedProducts(items, data.RelatedProducts)
                .ToImmutableList();

            return await items.InTask();
        }

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

        /// <summary>
        /// Mapping products to related products
        /// </summary>
        protected virtual IEnumerable<ProductSearchModel> AdornRelatedProducts(
            IImmutableList<ProductSearchModel> items,
            IImmutableList<RelatedProductDto> relatedProducts)
        {
            var groupedProducts = relatedProducts.ToLookup(x => x.ProductId);
            foreach (var model in items)
            {
                var ids = groupedProducts[model.Id]
                    .Select(x => x.RelatedProductId)
                    .ToList();

                yield return new ProductSearchModel(model) { RelatedProductIds = ids };
            }
        }
    }

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

builder.Services.AddSingleton<IAdorn<ProductSearchModel>, ProductRelatedProductAdorner>();

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

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

Last updated