Adding a property field to an index

Current version: 10.0

Sitecore Experience Commerce (XC) indexes Catalog entity properties (that is, properties of catalogs, categories, and sellable items) by default. When a Sitecore index rebuild is invoked, Commerce Engine minions add the indexed fields to the sitecore_web_index and the sitecore_master_index. The default indexes provide the ability to search for Commerce content items, for example Habitat catalog content items, in the Sitecore Content Editor, or in the SXA storefront. You can extend a search index by adding new fields to search on, including custom fields.

To introduce a new Commerce property field in a search index, you must map the new property field to a field type that the search provider can process. You can achieve this mapping through configuration in a policy set file, without the need to write or change code, assuming that you can map the new field to a default search field handler. The Search plugin and the Catalog plugin define default search field handlers used for catalog property mappings. If you cannot use an existing field handler, you can create a custom field handler.

Index field mapping definitions in the search policy set file

There are two approaches to consider when mapping a new field to an index. You can either map the new index field directly to a Commerce entity property, or you can use a computed field (such as a Solr dynamic field ), through a field handler implementation, similar to the way Sitecore uses computed fields in Solr field name resolution.

You add the new Commerce entity property to the index by defining the mapping to an index field type in the policy set file for your search provider (for example, PlugIn.Search.Solr.PolicySet.*.json file if you are using Solr). This policy set file resides on the instance of the Commerce Engine that is hosting the indexing role in your deployment (for example: C:\inetpub\wwwroot\CommerceMinions_Sc9\wwwroot\data\Environments).

In the policy set file, the ItemIndexablePolicy policy defines index field mappings in two main configuration sections: the "FieldTypeMappers" and "Fields" sections.

FieldTypeMappers configuration

The "FieldTypeMappers" section details a collection of IndexFieldTypeMapper configurations that define how different data types map to index fields. The following sample of the PlugIn.Search.Solr.PolicySet.*.json file shows an example of the default "FieldTypeMappers" definitions for the web index ("IndexName": "sitecore_web_index"):

RequestResponse
"$type": "Sitecore.Commerce.Core.PolicySet, Sitecore.Commerce.Core",
  "Id": "Entity-PolicySet-SolrSearchPolicySet",
  "Version": 1,
  "IsPersisted": false,
  "Name": "SolrSearchPolicySet",
  "Policies": {
    "$type": "System.Collections.Generic.List`1[[Sitecore.Commerce.Core.Policy, Sitecore.Commerce.Core]], mscorlib",
    "$values": [
      {     
      {

        "$type": "Sitecore.Commerce.Plugin.Search.ItemIndexablePolicy, Sitecore.Commerce.Plugin.Search",
        "IndexName": "sitecore_web_index",
        "FieldTypeMappers": [
          {
            "TypeName": "stringCollection",
            "Type": "System.Collections.Generic.List`1[System.String]",
            "NameFormat": "{0}_sm",
            "MultiValued": true
          },
          {
            "TypeName": "textCollection",
            "Type": "System.Collections.Generic.List`1[System.String]",
            "NameFormat": "{0}_txm",
            "MultiValued": true

FieldTypeMappers properties

The following table lists and describes properties of FieldTypeMappers configuration:

Properties

Description

"TypeName"

Defines the name of the field type.

"Type"

Specifies the class name that implements the type.

"NameFormat"

Defines the format of the type name.

"MultiValued"

Indicates whether a single document contains multiple values for this field type.

Fields configuration

The "Fields" section details a collection of configuration properties that define the actual mapping of a Commerce entity or component property to an index field. The following is an example of the default "Fields" section in the PlugIn.Search.Solr.PolicySet.*.json file.

RequestResponse
"$type": "Sitecore.Commerce.Core.PolicySet, Sitecore.Commerce.Core",
  "Id": "Entity-PolicySet-SolrSearchPolicySet",
  "Version": 1,
  "IsPersisted": false,
  "Name": "SolrSearchPolicySet",
  "Policies": {
    "$type": "System.Collections.Generic.List`1[[Sitecore.Commerce.Core.Policy, Sitecore.Commerce.Core]], mscorlib",
    "$values": [
     {     
     {
     {
     "FieldTypeMappers": [ 
     "Fields": [
          {
            "$type": "Sitecore.Commerce.Plugin.Search.Solr.SolrIndexFieldConfiguration, Sitecore.Commerce.Plugin.Search.Solr",
            "Name": "sxacontent",
            "Type": "System.Collections.Generic.List`1[System.String]",
            "TypeHint": "textCollection",
            "Handler": {
              "$type": "Sitecore.Commerce.Plugin.Catalog.SxaContentFieldHandler, Sitecore.Commerce.Plugin.Catalog"
            }
          },

Fields properties

The following table lists and defines properties of Fields:

Property

Definition

"$type"

Specifies references to the class name that implement the field type.

"Name"

Specifies the field name.

"Type"

The type format.

"TypeHint"

Defines the type of values that can be passed.

"Handler"

Specifies a reference to the class that defines the field handler.

"Localizable"

Specifies whether the field is a string that can be localized.

Policy set configuration examples

There are many ways of mapping a Commerce entity property to an index field. This section provides various configuration examples of field mappings.

Mapping configurations are defined in the policy set file PlugIn.Search.Solr.PolicySet.*.json if using the Solr search provider, or Plugin.Search.Azure.PolicySet.*.json if using Azure.

Note

All examples use Solr as the search provider. The same examples apply to Azure, but you must update the "$type" to "Sitecore.Commerce.Plugin.Search.Azure.AzureIndexFieldConfiguration, Sitecore.Commerce.Plugin.Search.Azure"

Example of 1:1 mapping where the index field name and the entity property are the same

The following shows an example where the index field name ("DisplayName") and the Commerce property name are the same. There is no need to specify a "ValueSource" to define Commerce property name.

RequestResponse
{
   "$type":"Sitecore.Commerce.Plugin.Search.Solr.SolrIndexFieldConfiguration,
   Sitecore.Commerce.Plugin.Search.Solr",
   "Name":"DisplayName",
   "Type":"System.String"
}

Example of a mapping where the index field name and the entity property name are different

There are cases where an index field name does not map directly to a static Commerce entity property name. The following shows an example:

RequestResponse
{
  "$type":"Sitecore.Commerce.Plugin.Search.Solr.SolrIndexFieldConfiguration, Sitecore.Commerce.Plugin.Search.Solr",
  "Name":"CatalogEntityId",
  "Type":"System.String",
  "ValueSource":{
      "PropertyName":"Id",
      "PropertyPath":""
  }
}

Example of a property mapping from a component using a different name for the field than the actual property name

The following shows an example where the index field DisplayPropertiesColor maps to a component display property defined using a "ValueSource".

RequestResponse
{
  "$type":"Sitecore.Commerce.Plugin.Search.Solr.SolrIndexFieldConfiguration,
Sitecore.Commerce.Plugin.Search.Solr",
  "Name":"DisplayPropertiesColor",
  "Type":"System.String",
  "TypeHint":"string",
  "ValueSource": {
      "PropertyName":"Color",
      "PropertyPath":"DisplayPropertiesComponent"
  }
}

Example of a mapping using custom field handler

The following shows an example where a custom handler is specified:

RequestResponse
{
   "$type":"Sitecore.Commerce.Plugin.Search.Solr.SolrIndexFieldConfiguration,
Sitecore.Commerce.Plugin.Search.Solr",
   "Name":"_UniqueId",
   "Type":"System.String",
   "Handler":{
     "$type":"Sitecore.Commerce.Plugin.Catalog.UniqueIdFieldHandler,
Sitecore.Commerce.Plugin.Catalog"
   }
}

Policy set configuration for indexing Composer-defined properties

When you add a view to define a custom property for a Catalog entity using a Composer template (that is, if you link the template to a catalog, category, or selleable item entity), you can add the new property field to the index.

Mapping configurations are defined in the policy set file PlugIn.Search.Solr.PolicySet.*.json if using the Solr search provider, or Plugin.Search.Azure.PolicySet.*.json if using Azure.

Note

All examples in this section use Solr as the search provider. The same examples apply to Azure, but you must update the "$type" to "Sitecore.Commerce.Plugin.Search.Azure.AzureIndexFieldConfiguration, Sitecore.Commerce.Plugin.Search.Azure"

Composer field handler

The Catalog plugin contributes the ComposerFieldHandler class that allows you to add a custom entity property defined using Composer to the index. The Composer field handler contains a "ComposerSource" section that specifies the name of the view within the Composer template, and the name of the custom property to map to an index field.

RequestResponse
"Handler": { 
  "$type": "Sitecore.Commerce.Plugin.Catalog.ComposerFieldHandler,
Sitecore.Commerce.Plugin.Catalog",
  "ComposerSource": {
  "ViewName": "MyViewName", 
  "PropertyName": "StringPropertyName"
    }

Configuration parameters of a Composer field handler are:

  • "$type": Specifies the class names that implement the ComposerFieldHandler

  • "Viewname": Specifies the child view name that defines the custom entity property.

  • "PropertyName": Specifies the name of the custom entity property that maps to an index field.

Note

The Viewname and PropertyName are those defined in the Catalog entity child view.

Example of mapping a Composer string property

The following shows a configuration example for mapping a custom Catalog entity property defined as a string data type to the appropriate index field type.

RequestResponse
{
 "$type": "Sitecore.Commerce.Plugin.Search.Solr.SolrIndexFieldConfiguration,
Sitecore.Commerce.Plugin.Search.Solr",
 "Name": "StringPropertyIndexName",
 "Type": "System.String",
 "Handler": {
   "$type": "Sitecore.Commerce.Plugin.Catalog.ComposerFieldHandler,Sitecore.Commerce.Plugin.Catalog",
   "ComposerSource": {
   "ViewName": "MyViewName",
   "PropertyName": "StringPropertyName"
  }
 }
}

Example of mapping a Composer integer property

The following shows a configuration example for mapping a custom Catalog entity property defined as an integer data type to the appropriate index field type.

RequestResponse
{ 
 "$type":
"Sitecore.Commerce.Plugin.Search.Solr.SolrIndexFieldConfiguration,
Sitecore.Commerce.Plugin.Search.Solr",
 "Name": "IntegerPropertyIndexName",
 "Type": "System.Int64",
 "Handler": {
   "$type": "Sitecore.Commerce.Plugin.Catalog.ComposerFieldHandler, Sitecore.Commerce.Plugin.Catalog",
   "ComposerSource": {
   "ViewName": "MyViewName",
   "PropertyName": "IntegerPropertyName"
  }
 }
}

Example of mapping a Composer decimal property

The following shows a configuration example for mapping a custom Catalog entity property defined as a decimal data type to the appropriate index field type.

RequestResponse
{
 "$type":
"Sitecore.Commerce.Plugin.Search.Solr.SolrIndexFieldConfiguration,
Sitecore.Commerce.Plugin.Search.Solr",
 "Name": "DecimalPropertyIndexName",
 "Type": "System.Decimal",
 "Handler": {
  "$type": "Sitecore.Commerce.Plugin.Catalog.ComposerFieldHandler, Sitecore.Commerce.Plugin.Catalog",
  "ComposerSource": {
    "ViewName": "MyViewName",
    "PropertyName": "DecimalPropertyName"
  }
 }
}

Example of mapping a Composer DateTimeOffSet property

The following shows a configuration example for mapping a custom Catalog entity property defined as a DateTimeOffSet data type to the appropriate index field type.

RequestResponse
{
 "$type":
"Sitecore.Commerce.Plugin.Search.Solr.SolrIndexFieldConfiguration,
Sitecore.Commerce.Plugin.Search.Solr",
 "Name": "DateTimeOffsetPropertyIndexName",
 "Type": "System.DateTimeOffset",
 "Handler": {
   "$type": "Sitecore.Commerce.Plugin.Catalog.ComposerFieldHandler,Sitecore.Commerce.Plugin.Catalog",
   "ComposerSource": {
     "ViewName": "MyViewName",
     "PropertyName": "DateTimeOffsetPropertyName"
  }
 }
}

Example of mapping a Composer Boolean property

The following shows a configuration example for mapping a custom Catalog entity property defined as a Boolean data type to the appropriate index field type.

RequestResponse
{
 "$type":
"Sitecore.Commerce.Plugin.Search.Solr.SolrIndexFieldConfiguration,
Sitecore.Commerce.Plugin.Search.Solr",
 "Name": "BooleanPropertyIndexName",
 "Type": "System.Boolean",
 "Handler": {
  "$type": "Sitecore.Commerce.Plugin.Catalog.ComposerFieldHandler, Sitecore.Commerce.Plugin.Catalog",
  "ComposerSource": {
    "ViewName": "MyViewName",
    "PropertyName": "BooleanPropertyName"
    }
  }

Updating the Solr configuration

If you are using Solr and you want to use this field for facets, you must create a configuration patch file that defines the new fields and data types. Put the configuration file in the /App_Config/Include/Z.Commerce.Engine folder. The following code is an example of a configuration patch file:

RequestResponse
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:search="http://www.sitecore.net/xmlconfig/search/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">

  <sitecore role:require="Standalone or ContentDelivery or ContentManagement" search:require="solr">
    <contentSearch>
      <indexConfigurations>
        <defaultSolrIndexConfiguration type="Sitecore.ContentSearch.SolrProvider.SolrIndexConfiguration, Sitecore.ContentSearch.SolrProvider">
          <fieldMap type="Sitecore.ContentSearch.SolrProvider.SolrFieldMap, Sitecore.ContentSearch.SolrProvider">
            <fieldNames hint="raw:AddFieldByFieldName">
              <field fieldName="stringpropertysolr" storageType="YES" indexType="TOKENIZED" vectorType="NO" boost="1f" returnType="string" settingType="Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration, Sitecore.ContentSearch.SolrProvider"/>
            </fieldNames>
          </fieldMap>
        </defaultSolrIndexConfiguration>
      </indexConfigurations>
    </contentSearch>
  </sitecore>
</configuration>

Updating the Azure configuration

In Azure deployment, when you add new fields to the index, you must also create a configuration patch file that defines the new fields and data types, and place the configuration file in the /App_Config/Include/Z.Commerce.Engine/ folder.

The following provides an example of a configuration patch file. You define new fields and field type mappings for Azure in the sections <fieldMap> and <documentOptions>.

RequestResponse
<configuration
xmlns:patch="http://www.sitecore.net/xmlconfig/"
xmlns:search="http://www.sitecore.net/xmlconfig/search/"
xmlns:role="http://www.sitecore.net/xmlconfig/role/">
  <sitecore role:require="Standalone or ContentDelivery or ContentManagement" search:require="azure">
    <contentSearch>
      <indexConfigurations>
        <defaultCloudIndexConfiguration type="Sitecore.ContentSearch.Azure.CloudIndexConfiguration,
Sitecore.ContentSearch.Azure">
          <fieldMap
type="Sitecore.ContentSearch.Azure.FieldMaps.CloudFieldMap,
Sitecore.ContentSearch.Azure">
            <fieldNames
hint="raw:AddFieldByFieldName">
              <field fieldName="stringpropertyazure" boost="1f" Type="System.String" settingType="Sitecore.Commerce.Engine.Connect.Search.CommerceCloudSearchFieldConfiguration,Sitecore.Commerce.Engine.Connect"/>
              <field fieldName="integerpropertyazure" boost="1f"
type="System.Int32"
settingType="Sitecore.Commerce.Engine.Connect.Search.CommerceCloudSearchFieldConfiguration,Sitecore.Commerce.Engine.Connect"/>
              <field fieldName="decimalpropertyazure" boost="1f"
type="System.Double"
settingType="Sitecore.Commerce.Engine.Connect.Search.CommerceCloudSearchFieldConfiguration,Sitecore.Commerce.Engine.Connect"/>
              <field fieldName="datetimeoffsetpropertyazure" boost="1f"
type="System.DateTimeOffset"
settingType="Sitecore.Commerce.Engine.Connect.Search.CommerceCloudSearchFieldConfiguration,Sitecore.Commerce.Engine.Connect"/>
              <field fieldName="booleanpropertyazure" boost="1f"
type="System.Boolean"
settingType="Sitecore.Commerce.Engine.Connect.Search.CommerceCloudSearchFieldConfiguration,Sitecore.Commerce.Engine.Connect"/>
            </fieldNames>
          </fieldMap>
          <documentOptions
type="Sitecore.ContentSearch.DocumentBuilderOptions,
Sitecore.ContentSearch">
            <fields hint="raw:AddComputedIndexField">
              <field fieldName="stringpropertyazure"
returnType="string">Sitecore.Commerce.Engine.Connect.Search.ComputedFields.CommerceComputedStringField, Sitecore.Commerce.Engine.Connect</field>
              <field fieldName="integerpropertyazure"
returnType="int">Sitecore.Commerce.Engine.Connect.Search.ComputedFields.CommerceComputedInt32Field, Sitecore.Commerce.Engine.Connect</field>
              <field fieldName="decimalpropertyazure"
returnType="double">Sitecore.Commerce.Engine.Connect.Search.ComputedFields.CommerceComputedDoubleField, Sitecore.Commerce.Engine.Connect</field>
              <field fieldName="datetimeoffsetpropertyazure"
returnType="string">Sitecore.Commerce.Engine.Connect.Search.ComputedFields.CommerceComputedDateTimeField, Sitecore.Commerce.Engine.Connect</field>
              <field fieldName="booleanpropertyazure"
returnType="bool">Sitecore.Commerce.Engine.Connect.Search.ComputedFields.CommerceComputedBooleanField, Sitecore.Commerce.Engine.Connect</field>
            </fields>
          </documentOptions>
        </defaultCloudIndexConfiguration>
      </indexConfigurations>
    </contentSearch>
  </sitecore>
</configuration>

Do you have some feedback for us?

If you have suggestions for improving this article,