Creating hierarchical facets

To navigate a very large content collection, sometimes site visitors need to use more than one filter. Hierarchical facets enable you to combine filters in a search, so your visitors can find specific results even from large, varied content collections.

This example demonstrates the use of a regular (flat) facet search in an API interaction, and explains the issues that can arise when using only this method of filtering.

Simple case of facets

Consider a car dealership with 16 cars currently available. They are organized by the facets car_brand, car_model, city, and car_year.

The cars available from the dealership organized by four different facets.
  • A car_brand can offer multiple models.

  • A car_model can have been manufactured in more than one year.

  • A car can be available for sale in more than one city.

In this example, there are 16 cars, each representing a combination of brand, model, city, and year. Search creates 21 facet objects to represent those combinations. These objects are associated with the data and the four facets, and their IDs are used in filter requests.

The following code displays a request made by a widget to display this information. The widget ID is rfkid_7.

{
    "context": {
        "locale": {
            "country": "us",
            "language": "en"
        }
    },
    "widget": {
        "items": [
            {
                "rfk_id": "rfkid_7",
                "entity": "car",
                "sources": [
                    "981588"
                ],
                "search": {
                 "limit":100,
                    "content": {
                        "fields": [
                            "car_brand",
                            "car_model",
                            "car_year",
                            "city"
                        ]
                    },
                    "facet": {
                        "max": 100,
                        "types": [
 
                            {
                                "name": "car_brand",
                                "filtering_options": ["hard_filters", "other_facet_values"]
                            },
                            {
                                "name": "car_model",
                                "filtering_options": ["hard_filters", "other_facet_values"]
                            },
                             {
                                "name": "car_year",
                                "filtering_options": ["hard_filters", "other_facet_values"]
                            },
                            {
                                "name": "city",
                                "filtering_options": ["hard_filters", "other_facet_values"]
                            }
                        ]
                    }
                }
            }
        ]
    }
 }

The following response contains the data returned by that request.

{
  "widgets": [
    {
      "rfk_id""rfkid_7",
      "type""content_grid",
      "used_in""page",
      "entity""car",
      "facet": [
        {
          "name""car_brand",
          "label""Brand",
          "value": [
            {
              "id""facetid_9ssdk0c13d7e384l6735y6904z30055yap70q8zw",
              "text""Ford",
              "count"10
            },
            {
              "id""facetid_9x7wb5q2cq323s80n47y4ha2a0791uct00r7743a",
              "text""Porsche",
              "count"6
            }
          ]
        },
        {
          "name""car_model",
          "label""Model",
          "value": [
            {
              "id""facetid_23738gzg2e5n984k3pu733kpf4y930fo18q80iri",
              "text""Fiesta",
              "count"1
            },
            {
              "id""facetid_12yrm13881j0ra2mgll579rmuz5gg2n4f01560d0",
              "text""Focus",
              "count"6
            },
            {
              "id""facetid_12yrm13881j0ra2mgll579rmuz5gg2n4f01560d1",
              "text""Kuga",
              "count"2
            },
            {
              "id""facetid_12yrm13881j0ra2mgll579rmuz5gg2n4f01560d2",
              "text""Ranger",
              "count"1
            },
            {
              "id""facetid_23738gzg2e5n984k3pu733kpf4y930fo18q80iri2",
              "text""Cayenne",
              "count"4
            },
            {
              "id""facetid_12yrm13881j0ra2mgll579rmuz5gg2n4f01560d3",
              "text""Macan",
              "count"1
            },
            {
              "id""facetid_12yrm13881j0ra2mgll579rmuz5gg2n4f01560d4",
              "text""Taycan",
              "count"1
            }
          ]
        },
        {
          "name""car_year",
          "label""Year",
          "value": [
            {
              "id""facetid_98spr93e7w49s9l1bobn72c06y94c18jzl64jj94",
              "text""2023",
              "count"2
            },
            {
              "id""facetid_yvfb0615m5ir28rz8wuq72038lf3ij43psm4m94x",
              "text""2022",
              "count"5
            },
            {
              "id""facetid_98spr93e7w49s9l1bobn72c06y94c18jzl64jj95",
              "text""2019",
              "count"1
            },
            {
              "id""facetid_yvfb0615m5ir28rz8wuq72038lf3ij43psm4m94y",
              "text""2018",
              "count"5
            },
            {
              "id""facetid_98spr93e7w49s9l1bobn72c06y94c18jzl64jj96",
              "text""2017",
              "count"3
            }
          ]
        },
        {
          "name""city",
          "label""City",
          "value": [
            {
              "id""facetid_fp1c8287ea7k71h6070hpg3x7a87mo79bcdz4xv4",
              "text""Kungsbacka",
              "count"1
            },
            {
              "id""facetid_5439e8r769543v350f86lx0845ygv60j20z2wmf9",
              "text""Bromma",
                            "count": 1
                        }
                    ]
                }
            ],
              "count"2
                    {
                    "card_brand": "Ford",
                    "car_model": "Fiesta",
                    "city": "Orlando",
                    "car_year": "2021",
                    "id": "64218"
                },
                {
                    "card_brand": "Kia",
                    "car_model": "Ceed SWPlug",
                    "city": "Atlanta",
                    "car_year": "2021",
                    "id": "64299"
                },
                {
                    "card_brand": "Kia",
                    "car_model": "XCeedPlug",
                    "city": "Seattle",
                    "car_year": "2021",
                    "id": "63932"
                }
            },
            {
              "id""facetid_fp1c8287ea7k71h6070hpg3x7a87mo79bcdz4xv5",
              "text""Eskilstuna",
              "count"2
            },
            {
              "id""facetid_5439e8r769543v350f86lx0845ygv60j20z2wmf0",
              "text""Molndal",
              "count"5
            },
            {
              "id""facetid_fp1c8287ea7k71h6070hpg3x7a87mo79bcdz4xv6",
              "text""Kristianstad",
              "count"3
            },
            {
              "id""facetid_5439e8r769543v350f86lx0845ygv60j20z2wmf1",
              "text""Segeltorp",
              "count"2
            },
            {
              "id""facetid_fp1c8287ea7k71h6070hpg3x7a87mo79bcdz4xv7",
              "text""Halmstad",
              "count"1
            }
          ]
        }
      ],
      "content": [
        {
          "car_brand""Ford",
          "car_model""Fiesta",
          "city""Kungsbacka",
          "car_year""2023",
          "id""64218"
        },
        {
          "car_brand""Ford",
          "car_model""Focus",
          "city""Bromma",
          "car_year""2022",
          "id""64219"
        },
        {
          "car_brand""Ford",
          "car_model""Kuga",
          "city""Eskilstuna",
          "car_year""2019",
          "id""64220"
        },
        {
          "car_brand""Ford",
          "car_model""Ranger",
          "city""Molndal",
          "car_year""2018",
          "id""64221"
        },
        {
          "car_brand""Porsche",
          "car_model""Cayenne",
          "city""Kristianstad",
          "car_year""2017",
          "id""64222"
        },
        {
          "car_brand""Porsche",
          "car_model""Macan",
          "city""Segeltorp",
          "car_year""2022",
          "id""64223"
        },
        {
          "car_brand""Porsche",
          "car_model""Taycan",
          "city""Halmstad",
          "car_year""2018",
          "id""64224"
        }
    ...
      ],
      "total_item"16,
      "limit"50,
      "offset"0
    }
  ],
  "dt"30,
  "ts"1727250342206
}

In this data:

  • Every item in the facet array has a value parameter containing the unique facet objects associated with that facet item, as created during indexing.

  • Every indexed car is listed in the content array, because the request did not include any facet filters.

Problem with increased number of facet values

As the number of cars in the inventory increases, the number of brands, models, years, and cities is likely to rise with it. This makes filtering with these four facets increasingly complex, creating additional overheads and lengthening response times.

For example, if the car dealership were to offer 6 models from 10 brands across 20 cities, the number of facet objects created during the indexing process would increase to 1,200 multiplied by the different years in which their car stock was manufactured. Including that many facet objects in the search.facet array for every request is inefficient and consumes excessive performance resources.

Using flat facets also complicates the way these items are presented in the frontend, as the relationship between brand and model is not apparent.

Solution for hierarchical facets

The solution to the problem in this example is to use hierarchical facets.

To combine filters in a search and use hierarchical facets, you must implement a hierarchical facet strategy.

If you have suggestions for improving this article, let us know!