DEV Community

loading...

Add a dynamic field for float collection to Solr managed schema

Takumi Yamada
Sitecore MVP 2020 - 2021, XP/Commerce certified developer.
Updated on ・2 min read

In Sitecore, there is no dynamic field for float collection in Solr managed schema. You can add it by taking the following steps.


① Add the following packages to your Visual Studio project.

  • Sitecore.ContentSearch.dll
  • Sitecore.ContentSearch.SolrProvider.dll
  • SolrNet.Core.dll

② Create a class inherit from the SchemaPopulateHelper, and override the GetAllFields method.

public class ExtendedSchemaPopulateHelper : SchemaPopulateHelper
{
    public ExtendedSchemaPopulateHelper(SolrSchema solrSchema) : base(solrSchema)
    {
    }

    public override IEnumerable<XElement> GetAllFields()
    {
        // definition of a dynamic field
        var floatCollectionField = new XElement("add-dynamic-field",
            new XElement("name", "*_fm"),
            new XElement("type", "pfloat"),
            new XElement("indexed", "true"),
            new XElement("stored", "true"),
            new XElement("multiValued", "true"));

        /* NOTE: You can use this.CreateField instead if you use Sitecore 9.3.

         var floatCollectionField = this.CreateField(
             name: "*_fm",
             type: "pfloat",
             required: false,
             indexed: true,
             stored: true,
             multiValued: true,
             omitNorms: false,
             termVectors: false,
             termPositions: false,
             termOffsets: false,
             isDynamic: true);
        */

        return base.GetAllFields().Append(floatCollectionField);
    }
}
Enter fullscreen mode Exit fullscreen mode

③ Create a class inherit from the PopulateFields, and override the GetHelper method.

public class ExtendedPopulateFields : PopulateFields
{
    protected override ISchemaPopulateHelper GetHelper(SolrSchema schema)
    {
        // return a customized helper instance
        return new ExtendedSchemaPopulateHelper(schema);
    }
}
Enter fullscreen mode Exit fullscreen mode

④ Replace the default processor to a customized one by configuration.

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:search="http://www.sitecore.net/xmlconfig/search/">
  <sitecore role:require="Standalone or ContentManagement or ContentDelivery" search:require="solr">
    <pipelines>
      <contentSearch.PopulateSolrSchema>
          <processor type="NamespaceTo.ExtendedPopulateFields, Assembly"
                     patch:instead="*[@type='Sitecore.ContentSearch.SolrProvider.Pipelines.PopulateSolrSchema.PopulateFields, Sitecore.ContentSearch.SolrProvider']" />
      </contentSearch.PopulateSolrSchema>
    </pipelines>
  </sitecore>
</configuration>
Enter fullscreen mode Exit fullscreen mode

⑤ Populate the Solr schema in the Control Panel.

Then, check your Solr schema in <solr>/server/solr/<core>/conf/managed-schema. You can find a definition of the dynamic field.

<dynamicField name="*_tf" type="pfloat" indexed="true" stored="true"/>
<dynamicField name="*_td" type="pdouble" indexed="true" stored="true"/>
<dynamicField name="*_pi" type="pint" indexed="true" stored="true"/>
<!-- *_fm should be added here -->
<dynamicField name="*_fm" type="pfloat" multiValued="true" indexed="true" stored="true"/>
<dynamicField name="*_t" type="text_general" indexed="true" stored="true"/>
<dynamicField name="*_i" type="pint" indexed="true" stored="true"/>
Enter fullscreen mode Exit fullscreen mode

If you want to map your (Sitecore's) field to this dynamic field, you have to configure field mapping like below. (it's just a sample)

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:search="http://www.sitecore.net/xmlconfig/search/">
  <sitecore role:require="Standalone or ContentManagement or ContentDelivery" search:require="solr">
    <contentSearch>
      <indexConfigurations>
        <defaultSolrIndexConfiguration type="Sitecore.ContentSearch.SolrProvider.SolrIndexConfiguration, Sitecore.ContentSearch.SolrProvider">
          <fieldMap type="Sitecore.ContentSearch.SolrProvider.SolrFieldMap, Sitecore.ContentSearch.SolrProvider">
            <typeMatches hint="raw:AddTypeMatch">
              <!-- Add a typeMatch -->
              <typeMatch typeName="floatCollection" type="System.Collections.Generic.List`1[System.Single]" fieldNameFormat="{0}_fm" multiValued="true" settingType="Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration, Sitecore.ContentSearch.SolrProvider" />
            </typeMatches>
            <fieldTypes hint="raw:AddFieldByFieldTypeName">
              <!-- Map your field (lowercase) to floatCollection -->
              <fieldType fieldTypeName="float list" returnType="floatCollection" />
            </fieldTypes>
          </fieldMap>
          <fieldReaders type="Sitecore.ContentSearch.FieldReaders.FieldReaderMap, Sitecore.ContentSearch">
            <param desc="id">defaultFieldReaderMap</param>
            <mapFieldByTypeName hint="raw:AddFieldReaderByFieldTypeName">
              <!-- Implement a field reader and configure for float list -->
              <fieldReader fieldTypeName="float list" fieldReaderType="NamespaceTo.FloatListFieldReader, Assembly" />
            </mapFieldByTypeName>
          </fieldReaders>
        </defaultSolrIndexConfiguration>
      </indexConfigurations>
    </contentSearch>
  </sitecore>
</configuration>
Enter fullscreen mode Exit fullscreen mode

I hope this post helps your Sitecore life.

Discussion (0)