Use dynamic facets

This is for:

Developer

Pilot Feature in 2.6063 (May 2019) Generally Available in 2.7610 (December 2019)

Dynamic facets embedded within a dynamic facet manager enables the Coveo Machine Learning (Coveo ML) Dynamic Navigation Experience (DNE) feature to automatically reorder facets and their values based on recorded usage analytics data representing past end-user interactions with a search interface (see About Dynamic Navigation Experience (DNE)).

Dynamic facets don’t support all of the features offered by Facet-inheriting components.

Be sure to review the dynamic facet limitations before upgrading a search interface to dynamic facets.

Prerequisites

  1. Create a DNE model.
  2. Associate the DNE model with a query pipeline.

Implementation Example

In a Coveo-powered commerce search page for technology-related products, you include dynamic facets based on the @prd_brand, prd_screen_size, @prd_total_storage, and @prd_processor_type facet-enabled fields in your index.

To do so, you configure three distinct DynamicFacet components and embed them all within the same DynamicFacetManager.

<div class="coveo-facet-column">
  <div class="CoveoDynamicFacetManager">
    <div class="CoveoDynamicFacet"
         data-field="@prd_brand"
         data-title="Brand"></div>
    <div class="CoveoDynamicFacet"
         data-field="@prd_screen_size"
         data-title="Screen size"></div>
    <div class="CoveoDynamicFacet"
         data-field="@prd_total_storage"
         data-title="Total storage"></div>
    <div class="CoveoDynamicFacet"
         data-field="@prd_processor_type"
         data-title="Processor type"></div>
  </div>
</div>

Queries originating from your commerce page are routed to a specific query pipeline. An active Coveo ML DNE model is associated with this pipeline. Therefore, depending on the current context, the model may automatically adjust the ranking scores of dynamic facets and their values.

For example, a customer searching for tablet may see entirely different facets than one searching for laptop:

Dynamic Facet Search for Classy Shirt

Rendering a set of dynamic facets in a static order

You may want some, or all dynamic facets in a search interface to appear in a specific order rather than being automatically reordered by the Coveo ML DNE feature.

The simplest way to achieve this is to avoid embedding those facets within a facet manager.

In a Coveo-powered commerce search page, you want the Price Range facet to always appear at the top of the interface, right over the Store facet.

Below those two facets, you want the Brand, Screen size, Total storage, and Processor type facets to appear in an order based on their respective ranking score values.

<div class="coveo-facet-column">
  <div class="CoveoDynamicFacet"
      data-field="@prd_price_range"
      data-title="Price Range"></div>
  <div class="CoveoDynamicFacet"
      data-field="@prd_store"
      data-title="Store"></div>
  <div class="CoveoDynamicFacetManager">
    <div class="CoveoDynamicFacet"
         data-field="@prd_brand"
         data-title="Brand"></div>
    <div class="CoveoDynamicFacet"
         data-field="@prd_screen_size"
         data-title="Screen size"></div>
    <div class="CoveoDynamicFacet"
         data-field="@prd_total_storage"
         data-title="Total storage"></div>
    <div class="CoveoDynamicFacet"
         data-field="@prd_processor_type"
         data-title="Processor type"></div>
  </div>
</div>

With the above configuration, no matter what the current context is, if the Price Range and Store facets contain values, they will always appear in the specified order at the top of the search page.

As an alternative, you can set the enableReorder option of a DynamicFacetManager component to false, to ensure that dynamic facets embedded within that facet manager appear in the order specified in the markup.

Doing so can be useful in more advanced use cases, such as if you want to use a facet manager to specify a custom behavior for a set of facets to render in a static order (see Defining Custom Dynamic Facet Behaviors).

Using custom dynamic facet sort functions

Rather than using the Coveo ML DNE feature, you may want to apply your own facet sorting mechanism to some, or all dynamic facets in a search interface.

You can use the compareFacets option of a DynamicFacetManager component to specify a custom sort function to apply to all dynamic facets embedded within that facet manager.

You create a custom function to sort dynamic facets embedded within the facetGroupA dynamic facet manager by descending number of selected values.

const sortFacetsByNumberOfSelectedValues = (facetA, facetB) => {
  facetBSelectedValues = facetB.values.selectedValues;
  facetASelectedValues = facetA.values.selectedValues;
  return facetBSelectedValues.length - facetASelectedValues.length;
};
Coveo.init(document.body, {
  facetGroupA: {
    compareFacets: sortFacetsByNumberOfSelectedValues
  }
});
<body id="search" class="CoveoSearchInterface">
  <!-- ... -->
  <div class="coveo-facet-column">
    <div id="facetGroupA"
         class="CoveoDynamicFacetManager">
      <div class="CoveoDynamicFacet"
           data-field="@source"
           data-title="Source"></div>
      <div class="CoveoDynamicFacet"
           data-field="@filetype"
           data-title="File Type"></div>
    </div>
    <div id="facetGroupB"
         class="CoveoDynamicFacetManager">
      <div class="CoveoDynamicFacet"
           data-field="@author"
           data-title="Author"></div>
      <div class="CoveoDynamicFacet"
           data-field="@language"
           data-title="Language"></div>
    </div>
  </div>
  <!-- ... -->
</body>

With the above configuration, the custom sort function only applies to dynamic facets embedded within the facetGroupA dynamic facet manager (that is, Source, and File Type). Facets embedded within the facetGroupB manager (that is, Author and Language) are sorted by ranking score.

Dynamic Facet Custom Sort

Defining custom dynamic facet behaviors

You can use the onUpdate option of a DynamicFacetManager component to specify a custom function to execute on each dynamic facet embedded within that facet manager, each time a query returns an updated facet response.

You create a custom function to collapse all dynamic facets except the first one whenever facets are updated.

const expandFirstFacetAndCollapseAllOthers = (facet, index) => {
  if (index > 0) {
    facet.collapse();
  } else {
    facet.expand();
  }
};

Coveo.init(document.body, {
  DynamicFacetManager: {
    onUpdate: expandFirstFacetAndCollapseAllOthers
  }
});
<body id="search" class="CoveoSearchInterface">
  <!-- ... -->
  <div class="coveo-facet-column">
    <div class="CoveoDynamicFacetManager">
      <div class="CoveoDynamicFacet"
           data-field="@source"
           data-title="Source"
           data-enable-collapse="true"></div>
      <div class="CoveoDynamicFacet"
           data-field="@filetype"
           data-title="File Type"
           data-enable-collapse="true"></div>
      <div class="CoveoDynamicFacet"
           data-field="@author"
           data-title="Author"
           data-enable-collapse="true"></div>
      <div class="CoveoDynamicFacet"
           data-field="@language"
           data-title="Language"
           data-enable-collapse="true"></div>
    </div>
  </div>
  <!-- ... -->
</body>

Dynamic Facet Custom Behavior

Dynamic facet limitations

DynamicFacetRange

Dynamic facets don’t currently support automatic range generation. Therefore, when configuring the DynamicFacetRange component, you must use the ranges option to request specific facet range values.

You may also want to replace FacetSlider and TimespanFacet components with DynamicFacetRange components.

DynamicHierarchicalFacet

You must configure the DynamicHierarchicalFacet component in search interfaces that leverage the DNE autoselection feature.

Unavailable features

The following “standard” facet functionalities aren’t currently supported by dynamic facets:

  • Sorting facet values:

    • Based on a computed field

    • Based on number of occurrences

    • Based on the Chi Square algorithm

    • In descending alphanumeric order

  • Allowing end users to modify facet settings

  • Allowing end users to exclude facet values

  • Creating conjunctive facets

  • Specifying an additional static query filter for a facet

Before the July 2019 release (v2.6459), the following components couldn’t be included in a search interface that contained dynamic facets (otherwise, queries would fail with the GroupBy and Facets can't both exist error):

  • CategoryFacet

  • Facet

  • FacetRange

  • FacetSlider

  • HierarchicalFacet

  • SimpleFilter

  • TimespanFacet

These components can now be used alongside dynamic facets. However, they must not be included in a dynamic facet manager, and will therefore always appear in a static order.

For technical reasons, facet search can’t perform optimally when a search interface includes both dynamic and non-dynamic facets.

In such a scenario, some expected facet search results may be filtered out.