# Custom Data

{% hint style="info" %}
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](/readme/search-and-indexing/indexing/index-definitions.md).
{% endhint %}

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:

{% code title="General properties" %}

```csharp
Task<IImmutableList<T>> Adorn(
            IImmutableList<T> items,
            DeserializedDataBase<T> rawData,
            CancellationToken token);
```

{% endcode %}

{% code title="Language-specific properties" %}

```csharp
Task<ImmutableDictionary<CultureInfo, IImmutableList<T>>> Adorn(
            ImmutableDictionary<CultureInfo, IImmutableList<T>> items,
            DeserializedDataBase<T> rawData,
            CancellationToken token);
```

{% endcode %}

{% hint style="danger" %}
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.
{% endhint %}

{% hint style="info" %}
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.
{% endhint %}

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

{% hint style="warning" %}
It is not recommended to use the id externally. This is also the reason the id is not part of the search model.
{% endhint %}

{% hint style="warning" %}
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.
{% endhint %}

```csharp
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:

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

{% hint style="info" %}
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.
{% endhint %}

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

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

{% hint style="warning" %}
A rebuild of the indices is needed after changing the index definition.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dev.ucommerce.net/readme/search-and-indexing/indexing/custom-data.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
