Adding a property field to an index

Abstract

How to add new property fields to an index through configuration, so that you can search for Commerce items in Sitecore using a new custom property as your keyword.

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.

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). 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_Sc\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"):

"$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.

"$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.

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 Solr policy set file PlugIn.Search.Solr.PolicySet.*.json.

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.

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

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

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

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

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

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

{
   "$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 Solr policy set file PlugIn.Search.Solr.PolicySet.*.json.

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.

"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.

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.

{
 "$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"
  }
 }
}

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.

{ 
 "$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"
  }
 }
}

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.

{
 "$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"
  }
 }
}

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.

{
 "$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"
  }
 }
}

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.

{
 "$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"
    }
  }

If you are using the Solr search provider, and you want to provide the ability to search using fields, you must create a configuration patch file that defines the new fields and data types. You add the configuration file in the /App_Config/Include/Z.Commerce.Engine folder. The following shows an example of a configuration patch file:

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