MongoDB Data Modeler Associate study materials
MongoDB Data Modeler Associate study resources

Evolving Product Attributes Without Migrations

MongoDB Data Modeler Associate · Put your knowledge to work in context.

All case studies

Evolving Product Attributes Without Migrations

An online marketplace is rebuilding its product catalog. It has 2 million SKUs across 40 categories. Each category defines 10 to 80 attributes, and the merchandising team adds or removes attributes every week. Mobile and web clients cache category schemas and may be several releases behind. The current documents embed category-specific fields at the top level, so application code branches on category and handles missing fields inconsistently. Queries include: filter by category plus two or three attributes, for example brand=Sony and screenSize=55; sort by price; and full-text search on title and description. Reports frequently ask for counts by an attribute that was added last month. The team wants a model that accommodates new attributes without migrations and supports efficient multi-attribute filtering.

1. Propose a document structure using the attribute pattern and schema versioning. Show how a new attribute is added and how old clients stay compatible.

Read the worked answer

Keep stable, frequently queried fields at the top level: sku, categoryId, title, description, price, currency, schemaVersion, and status. Put category-specific attributes in an attributes array of key-value pairs:

{ sku, categoryId, schemaVersion: 3, title, price,
  attributes: [ { k: 'brand', v: 'Sony' },
                { k: 'screenSize', v: 55 } ] }

This avoids adding a new top-level field for every attribute and avoids rewriting old documents when the catalog changes. schemaVersion tells clients and the API which shape or semantics they are reading. Old clients should not read the raw attributes array directly; the API projects a compatibility view based on schemaVersion and ignores unknown keys. New attributes are introduced by adding a definition in a category-attribute metadata collection and then writing new array entries. Existing documents need no migration; a backfill is needed only if the new attribute must be searchable or reported on immediately. Validate types and allowed values in the application layer because the array is flexible by design.

2. How would you index the catalog for category plus two or three attribute filters, price sort, and full-text search? Discuss limitations of multikey indexes and alternatives.

Read the worked answer

Category plus price sort is straightforward: { categoryId: 1, price: 1 }.

Attribute filtering is harder. A compound multikey index on attributes.k and attributes.v from the same array is not a general solution, and multiple attribute predicates cannot all be served efficiently by one array index. Practical options are: promote the most common filtering attributes to top-level fields and create compound indexes such as { categoryId: 1, brand: 1, screenSize: 1, price: 1 }; use a wildcard index on attributes.v or attributes.$** for single-attribute lookups; store a normalized token array such as ['brand:Sony', 'screenSize:55'] and index it for $all queries; or use Atlas Search for multi-attribute faceting and text search.

Full-text search on title and description should use a text index or Atlas Search; a text index allows only one per collection and has limited scoring and language features. For a marketplace, Atlas Search is usually the better fit because it combines text, faceting, and attribute filters. The key judgement is not to pretend one index solves every combination. Index the top query shapes, use wildcard or search for the long tail, and measure which attribute combinations are common enough to justify a compound index.

3. What are the risks of the attribute pattern for reporting counts by a newly added attribute, and how would you support that query?

Read the worked answer

The main risk is that a new attribute has no index and no consistent type, so a count by that attribute becomes a collection scan or produces inconsistent results when values are stored as strings in some documents and numbers in others. Reports also need to handle documents that predate the attribute and therefore have no entry at all.

Support the query by defining the attribute type and semantics in the metadata collection before rollout, then backfilling a normalized value for existing SKUs if the report must be complete immediately. For ad hoc counts, a wildcard index on attributes.v can support equality on a single value, but it does not efficiently pair k and v for arbitrary attributes. If the attribute becomes important, promote it to a top-level field with a compound index or write a nightly aggregation into a reporting collection. Use schemaVersion and validation to keep types consistent.

The tradeoff is write cost and complexity: every promoted attribute adds index maintenance and application code. Promote only attributes that are queried or reported frequently, and keep the long tail in the attributes array.