1) Vì sao cần thiết kế chuyên biệt?

Trong e-commerce, trình bày sản phẩm (Catalog) và tìm kiếm (Search) là cửa ngõ đầu tiên người dùng tiếp xúc:
  • Người dùng kỳ vọng tìm sản phẩm nhanh, chính xác, gợi ý thông minh
  • Cần xử lý hàng trăm nghìn đến hàng triệu SKU
  • Cần hỗ trợ bộ lọc đa tiêu chí, phân trang, sort, gợi ý từ khóa, synonym, đánh vần gần đúng
  • Nếu thiết kế không chuẩn → chậm, không liên quan, không tìm thấy → mất doanh thu

2) Tổng quan kiến trúc

[User] 
  ↓
[Search API / Catalog API (BFF)]
  ↓
[Search Engine (:contentReference[oaicite:0]{index=0} / :contentReference[oaicite:1]{index=1})]
  ↓
[Index Builder] ← [Product DB / Pricing / Inventory / Metadata]
         ↓
[Event Bus (:contentReference[oaicite:2]{index=2}/:contentReference[oaicite:3]{index=3})] ← [Product Service / Inventory Service]
  • Catalog API đọc dữ liệu sản phẩm, giá, tồn, metadata đã được index hóa để trả về nhanh.
  • Index Builder build/làm mới index từ DB gốc theo batch hoặc real-time events.
  • Search Engine dùng inverted index để truy vấn full-text, phân trang, sort, filter rất nhanh.

3) Thiết kế dữ liệu Catalog

3.1 Product Model

{
  "product_id": "P123",
  "name": "Áo thun nam cotton",
  "description": "...",
  "brand": "BrandA",
  "categories": ["Áo", "Nam"],
  "attributes": {
    "mau": ["Đỏ", "Xanh"],
    "size": ["S", "M", "L"]
  },
  "variants": [
    { "sku": "P123-R-S", "color": "Đỏ", "size": "S", "price": 250000, "stock": 5 },
    ...
  ],
  "price_min": 250000,
  "price_max": 300000,
  "rating": 4.7,
  "review_count": 325,
  "created_at": "2024-05-01"
}

3.2 Chuẩn hóa dữ liệu

  • Tách product vs variant (đơn vị bán thực tế)
  • Lưu price snapshot và inventory snapshot trong index để query nhanh
  • Chuẩn hóa brand, category sang ID, dùng keyword field để sort/filter

4) Thiết kế Search Engine

4.1 Các loại query thường dùng

  • Full-text search: tìm theo tên/mô tả (match, multi_match)
  • Prefix search / autocomplete: gợi ý khi gõ (completion suggester)
  • Synonym & typo tolerance: ánh xạ từ đồng nghĩa (“quần jean” = “quần bò”), sửa chính tả (fuzziness)
  • Filter: brand, category, khoảng giá, còn hàng, màu sắc… (bool + filter)
  • Sort: theo giá, ngày tạo, độ phổ biến, điểm search relevance
  • Pagination: from+size (small result) hoặc search_after (khi >10k sản phẩm)

4.2 Ranking & Relevance

  • Boost sản phẩm mới, hàng còn nhiều, bán chạy
  • Personalization: dùng lịch sử người dùng để sắp xếp lại kết quả
  • A/B testing: thử nhiều chiến lược ranking để tối ưu chuyển đổi

5) Đồng bộ dữ liệu Catalog → Search index

5.1 Batch build (ETL)

  • Build lại toàn bộ index 1–2 lần/ngày từ DB gốc
  • Dễ vận hành nhưng có độ trễ

5.2 Real-time event-driven

  • Khi sản phẩm cập nhật/tạo mới/tồn kho thay đổi, publish event ProductUpdated, InventoryChanged
  • Index Builder lắng nghe và update incrementally
  • Giúp kết quả tìm kiếm luôn gần như real-time
Có thể dùng dual-write (ghi DB + push event) + outbox pattern để đảm bảo không mất event.

6) Bộ lọc (Faceted Search)

  • Tạo aggregation buckets theo brand, category, price range, rating
  • Chỉ lấy facet từ kết quả hiện tại (contextual filter)
  • Cache kết quả aggregation để giảm tải

7) Performance và Scaling

  • Dùng Redis hoặc CDN cache query phổ biến
  • Sharding index nếu > 50 triệu documents
  • Replicas để scale đọc, ILM (Index Lifecycle Management) xoay index cũ
  • Giới hạn fields trả về, chỉ trả product_id, name, thumbnail, price

8) Kết nối với các service khác

  • Inventory Service: đồng bộ stock để ẩn sản phẩm hết hàng
  • Pricing Service: cập nhật giá động (khuyến mãi, flash sale)
  • Recommendation Engine: lấy danh sách sản phẩm đề xuất để hiển thị song song search
  • Analytics: ghi lại search_query, click, add_to_cart để cải thiện relevance

9) Kết luận

Module Search & Catalog là trái tim frontend của hệ thống thương mại điện tử:
  • Catalog chuẩn → dữ liệu sạch, dễ query
  • Search engine mạnh → kết quả nhanh, chính xác, có đề xuất thông minh
  • Đồng bộ real-time → giá, tồn kho luôn đúng
  • Ranking linh hoạt → tăng chuyển đổi & doanh thu
Gợi ý: Bắt đầu với batch indexing đơn giản, sau đó dần chuyển sang event-driven + personalization khi hệ thống lớn lên.