Skip to main content
A search result represents one record. Algolia matches, ranks, filters, and updates , including values nested in arrays, so how you split your data into records determines what users can find, how they , and how you keep your index up to date. This guide helps you decide what one record represents, with examples from a games marketplace and an ecommerce catalog.

Record levels

  • An item is the smallest thing users could see as a separate result, such as a product variant, a listing, or a page section.
  • A parent is what items belong to, such as a product, a game, or a page.
You can represent items and parents at three levels:
  • Child-level records: one record per item. Each record holds its parent’s identifier and any parent attributes you need.
  • Group-level records: one record per group of items that share a value, such as one record per color of a product. Store shared attributes at the top level and attributes that differ between items in an array.
  • Parent-level records: one record per parent. Store all items in an array.

Choose a record level

Each level favors different requirements. Compare them before you decide: If you use Recommend, child-level records can still give you recommendations per parent. With Recommend deduplication Algolia merges events from variants of the same item and uses one variant per item in the training dataset. Use this guidance to choose:
  • Use child-level records if users filter on combinations of item attributes or item data changes often.
  • Use parent-level records if users don’t filter on combinations of item attributes and you want events, rules, and analytics for the whole parent. When an item changes, you must update the parent record’s item array.
  • Use group-level records if users filter on a shared group attribute, such as color, and you want events, rules, and analytics for each group. Use this model only if it’s acceptable for filters on attributes in the item array to match different items.

Child-level records

Use child-level records when your source data has parents and children, such as a game and its listings, a product and its variants, or a page and its sections.

Index child records

  • Create one record per child. Don’t create records for parents in this index.
  • Store the parent’s identifier in each child, such as game_id or product_id.
  • Decide how much parent data to copy into each child:
    • Copy the attributes users search, filter, rank, or display. For example, copy the game’s title into each listing. When the parent changes, update every child record that copies the changed attribute.
    • Store only the identifier. You can change the parent’s details without reindexing its children, but users can’t search or filter on parent details that aren’t in the child.
For example, to let users search movies and group them by director, index one record per movie with a director attribute:
JSON
Because every record repeats the director, a search for miyazaki can return all his movies.

Show one result per parent

Set attributeForDistinct to the parent identifier and distinct to true. Algolia returns the best-ranked matching child from each group. Your ranking formula determines which child it selects. Each result remains one child record: Algolia doesn’t merge the records in the group. In the movie example, set attributeForDistinct to director and add desc(score) to customRanking. A search for miyazaki returns one movie per director. If his movies have equal scores for the earlier ranking criteria, Algolia returns his highest-scoring movie. Facet counts show how many matching records have each attribute value, such as a category. If you use distinct to show one result per parent, facet counts still count matching children by default. For attributes whose values are identical across all children of a parent, such as category, use the afterDistinct modifier in attributesForFaceting to count parents instead.

Plan for updates and record counts

  • Updates. To update a child record, send a partial update with the changed attributes. If a changed value is nested, include the entire top-level attribute that contains it.
  • Record count. Each child is a separate record. For example, 10,000 games with ten listings each require 100,000 listing records. Check your plan’s quotas and Algolia’s service limits before you choose this model.

Parent-level records

Use parent-level records when users search for the parent and you don’t need to treat its items as separate results. Put the shared attributes at the top level and the items in an array:
JSON
A query matches the whole record. Because the array holds several items, keep these two effects in mind:

Group-level records

Use group-level records when items split naturally by one attribute, and users filter or select on that attribute first. For example, you can create one record per color of a product. Put the shared attributes and the grouping attribute at the top level, and put the attributes that differ between items in an array. This keeps filters on the grouping attribute exact while giving you events, rules, and analytics per group. Conditions on attributes inside the array can still match different items in the same group. For a worked example, see Ecommerce records.

Record structure examples

The following examples show each level for a games marketplace and an ecommerce catalog.

Marketplace records

In a games marketplace, a listing is one seller’s offer for one game. A listing belongs to both a game and a seller, so you can treat either as the parent. Which record level fits depends on what users search for:
  • Seller records (parent-level) when users want to find sellers and browse their games.
  • Game records (parent-level) when users want to find games and see who sells them.
  • Listing records (child-level) when users want to compare offers, rank them by seller attributes, or filter on combinations of listing attributes.
Create one record per seller. Keep only the attributes users search, filter, or display, and list the titles of the games they sell in a games array:
JSON
To give matches in seller names higher attribute priority than matches in game titles, list name before games in searchableAttributes.Users can’t filter on anything about a game beyond its title.

Ecommerce records

Consider a t-shirt sold in white in sizes M and L, and in blue in size L. Each available color-and-size combination is a variant, so this product has three variants. You can store this variant data in Algolia at three levels:
  • Variant-level records (child-level). Create one record for each variant.
  • Product-level records (parent-level). Create one record for each base product. The common attributes sit at the top level. The varying attributes, such as image and price, sit in a variants array.
  • Grouped variant records (group-level). Create one record for each value of a chosen attribute, such as color. Store shared attributes at the top level and size-specific attributes in a variants array.
JSON
To show one result per product, set attributeForDistinct to product_id and distinct to true.If results show color swatches or image carousels, your frontend needs data about sibling variants. You can copy that data into each variant record, but doing so increases record size.

Color and size filters

To filter these examples by color and size, set attributesForFaceting for the record model you use:
  • Variant-level records: ["color", "size"]
  • Product-level records: ["variants.color", "variants.size"]. With product-level records, variants.color:Blue AND variants.size:M matches v-neck-t-shirt. One variant supplies Blue and another supplies M, although the product doesn’t have a blue variant in size M.
  • Grouped variant records: ["color", "variants.size"]. With grouped variant records, color:Blue AND variants.size:M doesn’t match v-neck-t-shirt-blue, because that record contains only a blue variant in size L. Within a color group, conditions on variants.size and variants.price can still match different variants.
To decide between these models, see Choose a record level. Record level is one of several data modeling decisions. For the others, see:
Last modified on November 11, 2026