Skip to main content
In ecommerce, you often deal with base products and their variants. For example, a t-shirt (the base product) might be available in different colors and sizes (the variants). You can store this data in Algolia in two ways:
  • Variant-level records: one Algolia record for each product variation.
  • Product-level records: one Algolia record for each base product. All variations are contained in this record.

Record structure examples

The following example shows records for a t-shirt available in two color. Each color is available in two sizes. With the variant-level records model, each variant is a separate record:
JSON
[
  {
    "name": "V-neck t-shirt",
    "category": "Sport",
    "color": "White",
    "size": "M",
    "image": "v-neck-t-shirt-white.jpg",
    "price": 19.99
  },
  {
    "name": "V-neck t-shirt",
    "category": "Sport",
    "color": "White",
    "size": "L",
    "image": "v-neck-t-shirt-white.jpg",
    "price": 19.99
  },
  {
    "name": "V-neck t-shirt",
    "category": "Sport",
    "color": "Blue",
    "size": "M",
    "image": "v-neck-t-shirt-blue.jpg",
    "price": 22.99
  },
  {
    "name": "V-neck t-shirt",
    "category": "Sport",
    "color": "Blue",
    "size": "L",
    "image": "v-neck-t-shirt-blue.jpg",
    "price": 22.99
  }
]
With the product-level records model, all variants of a base product are in a single record. The common attributes are at the top level. The varying attributes (color, size, images, and prices) are nested in a variants array. Each array item corresponds to a unique variant:
JSON
{
  "name": "V-neck t-shirt",
  "category": "Sport",
  "variants": [
    {
      "color": "White",
      "size": "M",
      "image": "v-neck-t-shirt-white.jpg",
      "price": 19.99
    },
    {
      "color": "White",
      "size": "L",
      "image": "v-neck-t-shirt-white.jpg",
      "price": 19.99
    }
    {
      "color": "Blue",
      "size": "M",
      "image": "v-neck-t-shirt-blue.jpg",
      "price": 22.99
    },
    {
      "color": "Blue",
      "size": "L",
      "image": "v-neck-t-shirt-blue.jpg",
      "price": 22.99
    }
  ]
}

Choose your record model

When choosing between the two indexing models, consider whether you use Algolia AI or merchandising features. Use the product-level record model if you use Algolia AI or merchandising features. This model can be more effective if your products share many similarities between variants:
  • Click and conversion events from each variant are grouped by base product. This lets the AI re-rank or personalize results at the product level and not only for specific variants.
  • It’s easier to manage rules and merchandising at the product-level—when dealing with many variants at once. For example, you can promote or hide products rather than individual variants.
  • Search analytics results are grouped by product, making them easier to analyze.
Use the variant-level record model if you don’t use Algolia AI or merchandising. This model is more granular and better suited for precise control:
  • Results match the most relevant variant directly. For example, a search for “red shoes” returns only variants with “red” in their data. In contrast, the product model requires additional frontend work to display the correct variant.
  • Faceting is more accurate. A filter like color: green AND size: 40 returns only matching variants, not entire products with partial matches.
  • You can update individual variant attributes (like price or stock). The product model requires resending the full list of variants, as partial updates aren’t supported.

Capabilities by record model

Variant-levelProduct-level
AI featuresPer variantPer product
Rules and merchandisingPer variantPer product
Search analyticsPer variantPer product
Textual relevanceOptimizedSupported
Faceting supportOptimizedRequires frontend work (see below)
Variant-powered PLPOptimizedRequires frontend work (see below)
Granular variant updateSupportedNot supported
Average record sizeDepending on further choices (see [Average record size](#average-record-size for the variant-level model))Optimized
Number of recordsHighOptimized

Average record size for the variant-level model

The average record size for the variant-level model depends on what you want to show on your results, for example, if you want to include color swatches or images carousels. To display those, each of your variant records needs to have information about their siblings, which increases the average record size.

Results display

Group records per product

Depending on your desired end-user experience and catalog size, showing a single result per product—rather than listing each variant separately— can offer a cleaner and more user-friendly interface. With the product-level record model, you get one result per product by default. The variant-level model requires using the distinct feature to group variants under a single result. To do this, include a shared product ID in each variant record and set the distinct parameter on that attribute:
JSON
{
  "name": "V-neck t-shirt",
  "baseProductID": "v-neck-t-shirt-001",
  // ...
}

Facets

Users can refine results more easily with the variant-level record model. In this model, Algolia returns only the variants that match the selected facets— no additional frontend logic required. In contrast, the product-level model always returns the entire product, including all variants. To display only the matching variants, you need to post-process the search results in your InstantSearch code:
JavaScript
hits({
  // ...
  transformItems(items, { results }) {
    return items.map((item) => {
      const colorFacets = results._state.disjunctiveFacetsRefinements['variants.color'] || [];

      let selectedVariant;
      if (colorFacets.length > 0) {
        selectedVariant = item.variants.find(variant => {
            return colorFacets.includes(variant.color);
        });
      } else {
        selectedVariant = item.variants[0];
      }

      item.image = selectedVariant.image;
      item.price = selectedVariant.price;
      item.url = selectedVariant.url;

      return item;
    });
  },
});
I