Ucommerce
  • Ucommerce Next Gen
    • Getting Started
      • Prerequisites
      • Licensing
      • Ucommerce Templates
      • Headless Template
      • MVC Template
    • Headless
      • Postman Collection
      • Headless API Authentication
        • Token endpoint - Authorization Header
        • Authorization Scopes
        • Refreshing the Access Token
      • Reference
        • Cart
        • Cart / Order Line Items
        • Shipment
        • Billing
        • Promotion Codes
        • Price Groups
        • Payment Methods
        • Countries
        • Shipping Methods
        • Catalogs
        • Cart Custom Properties
        • Line Item Custom Properties
        • Orders
        • Views for Cart modifying operations
      • Custom Headless APIs
      • Error Handling
      • Pagination
      • Deprecation
    • Backoffice Authentication
      • Microsoft Entra ID Example
      • Auth0 Authentication Example
    • Definitions
      • What is a Definition
    • Search and indexing
      • Configuration
      • Indexing
        • Index Definitions
        • Facets
        • Indexing Prices
        • Suggestions
        • Custom Data
      • Searching
    • Payment Providers
      • Stripe Provider Integration
      • Implementing a custom payment provider
    • Data Import
    • Miscellaneous
      • Media
      • Price Group Inheritance
      • Price Group Criteria
      • Soft Deletion Of Entities
      • Logging
      • OpenTelemetry
    • Extensions
      • Extending Pipelines
        • Order Processing Pipelines
        • Checkout Pipelines
      • Changing Service Behavior
        • Images
        • Content
      • Custom Headless APIs
      • Extend the Backoffice
        • Custom UI Components
      • Custom Editor UI
      • Custom Promotion Criteria
      • Custom Price Group Criteria
    • How-To
      • Migrate from Classic
        • Common database issues
      • Entities from code
        • Bootstrapping data on startup
        • Product Definitions & Fields
      • Discover pipelines and their tasks
      • Executing a pipeline
    • Integrations
      • Umbraco Media Delivery API
      • App Slices
        • Product Picker
  • Release Notes
  • Contact Us
Powered by GitBook
On this page

Was this helpful?

  1. Ucommerce Next Gen
  2. Search and indexing
  3. Indexing

Custom Data

Add custom or external data to your index.

PreviousSuggestionsNextSearching

Last updated 9 months ago

Was this helpful?

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

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);

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.

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.

It is not recommended to use the id externally. This is also the reason the id is not part of the search model.

The below adorner is not meant for production as it is not very performant to make a database call for each product to get the id.

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));

A rebuild of the indices is needed after changing the index definition.

custom index definition