Katkat

Design Faceted Product Search at Large Scale

AmazonSoftware Engineer · Onsite

Last updated

Design a scalable e-commerce product search engine supporting full-text query matching, multi-attribute filtering, dynamic facet aggregations, and near real-time updates for volatile data like price and inventory.

Scenario

Design the product search and filtering backend for a massive e-commerce platform. Shoppers search using free-text queries (e.g., "wireless noise cancelling headphones") and narrow results via faceted navigation such as brand, category taxonomy, price range, and customer ratings. In addition to ranked product results, the system must return accurate facet counts indicating how many matching items exist within each facet bucket.

Requirements

Functional Requirements

  • Relevance Search: Free-text query matching over product titles, descriptions, and keywords with text relevance scoring.
  • Faceted Search & Filtering: Support filtering by category, brand, rating, and dynamic price ranges, returning matching products alongside facet aggregations.
  • Deterministic Pagination: Support stable, paginated browsing through search results without duplicate or missing items across page boundaries.
  • Volatile Field Updates: Propagate rapid price changes and out-of-stock inventory status into search results within seconds.

Non-Functional Requirements

  • Scale: 1 billion active catalog products; 50,000 search queries per second (QPS) at peak.
  • Latency: p99 query latency under 150 ms (including facet computation).
  • High Availability: 99.99% availability for the read path.
  • Update Throughput: 5,000 catalog attribute updates/sec and up to 50,000 price/stock status updates/sec.

What to Cover

  1. High-Level Architecture & API Design: Define search endpoints, request parameters (query, filters, facets, cursor), and the response structure.
  2. Index Structure & Storage: Detail the inverted index for text, forward indexes (columnar doc values) for filtering and aggregation, and the sharding strategy (e.g., document-based vs. term-based).
  3. Query Execution & Aggregations: Explain the step-by-step lifecycle of a search request across coordinator nodes and leaf shards, including posting list intersection, scoring, facet aggregation, and scatter-gather merging.
  4. Handling Rapid Price & Availability Updates: Contrast naive index re-indexing with hybrid architectures (e.g., in-memory sidecar stores, delta segments, or two-phase hydration).
  5. Pagination & Trade-offs: Compare offset-based pagination against keyset/cursor-based approaches at high volume.

Hints

Hint 1

Consider how inverted indexes handle text token lookups whereas columnar structures (DocValues) are far more efficient for facet counts and range filters.

Hint 2

Re-indexing the entire Lucene/search document for every price or stock change creates massive I/O write amplification; consider decoupling volatile attributes into a fast in-memory key-value store or dedicated delta index.

Hint 3

Think about how distributed facet counts are merged across shards, especially when multi-select filtering is enabled for facets in the same dimension.

Follow-up questions

  • How would you address the deep pagination problem (e.g., requesting page 500) across distributed shards without exhausting coordinator memory?
  • How does your facet calculation logic change when a user selects multiple values within the same facet dimension (e.g., Brand = 'Sony' OR Brand = 'Bose') versus across dimensions?
  • If a merchant changes a product's price during a flash sale, how do you prevent race conditions where the search card displays a stale price that mismatches the product detail page?