Quản lý sản phẩm (PIM)Sản phẩm

Tìm kiếm sản phẩm

API tìm kiếm sản phẩm nâng cao với bộ lọc, phân trang và aggregation (Facets).

Endpoint

POST /site/products/search

Headers

KeyValueBắt buộcMô tả
SiteTenantId{tenant_id}CóID của công ty/tenant.

Workflow & Logic

API này hoạt động theo mô hình Search-First, truy xuất dữ liệu từ chỉ mục tìm kiếm ElasticSearch của shop để đảm bảo hiệu năng cao khi lọc và thống kê (aggregation). Sau khi có danh sách ID từ ES, hệ thống sẽ Enrich (làm giàu) dữ liệu từ Database để đảm bảo tính chính xác nhất về giá, tồn kho và các thông tin chi tiết.

Quy trình xử lý (Internal Processing)

  1. Khởi tạo (Initialization):

    • Xác định company_id hiện tại.
    • Tải cấu hình hệ thống (Setting), quan trọng nhất là website_price_policy_id để xác định chính sách giá áp dụng cho website (áp dụng chung cho mọi khách, không phụ thuộc khách đăng nhập).
  2. Xử lý Bộ lọc (Filter Processing):

    • Visibility:

      • Mặc định chỉ lấy sản phẩm có trạng thái VISIBILITY_SHOW và VISIBILITY_CATALOG_ONLY.
      • Nếu có từ khóa keyword, bổ sung thêm VISIBILITY_SEARCH_ONLY.
      • with_attachment=1: Cho phép hiển thị sản phẩm quà tặng/phụ kiện (VISIBILITY_ATTACHMENT).
    • Price Range: Phân tích chuỗi price (VD: 0-100000.200000-500000) thành các khoảng giá để query ES.

    • Product Options: Giải mã chuỗi productoption (VD: optionID:valID1,valID2) để lọc theo thuộc tính động.

    • String Facet: Lọc theo các thuộc tính dạng chuỗi (dynamic attribute) gửi qua request body.

    • Chỉ lấy sản phẩm đang hoạt động (status = 3) và khớp tất cả điều kiện lọc.

  3. Truy vấn Search Engine (ES Query):

    • Thực hiện query tới ElasticSearch với các tiêu chí lọc.
    • Tính toán Aggregations (Facets) theo yêu cầu từ tham số aggs (VD: đếm số lượng theo Brand, Category).
  4. Làm giàu dữ liệu (Data Enrichment):

    • Từ danh sách ID trả về bởi ES, hệ thống lấy dữ liệu thẻ sản phẩm (product card) mới nhất của từng sản phẩm (sản phẩm đã bị xóa sẽ bị loại khỏi items):

      • Variants & Pricing: Tính toán giá thực tế dựa trên Policy (Giá chính sách > Giá UOM > Giá gốc).
      • Selectable Options: Tính toán ma trận tùy chọn (Màu/Size) khả dụng dựa trên các Variants thực tế. Giúp Frontend ẩn các nút không có hàng.
      • Social Videos: Tự động parse link (TikTok/Youtube) thành ID video nhúng.

Query Parameters

Mặc dù dùng phương thức POST, các tham số lọc dưới đây được đọc từ query string (URL). Riêng string_facet được gửi trong request body (JSON).

TênKiểuBắt buộcMô tả
keywordstringKhôngTừ khóa tìm kiếm.
category_idintegerKhôngLọc theo ID danh mục chính xác.
category_id_liststringKhôngLọc theo danh sách ID danh mục (cách nhau dấu phẩy).
brandstringKhôngLọc theo danh sách ID thương hiệu (cách nhau dấu phẩy).
pricestringKhôngLọc theo khoảng giá. VD: 0-100000 hoặc 0-100000.200000-500000 (nhiều khoảng). Mỗi khoảng phải có from <= to và to >= 100000, khoảng không hợp lệ bị bỏ qua.
productoptionstringKhôngLọc theo thuộc tính. Format: optionID:valueID,valueID|optionID2:valueID.
idsstringKhôngLọc theo danh sách ID sản phẩm cụ thể (cách nhau dấu phẩy, tối đa 100 ID).
aggsstringKhôngDanh sách aggregation cần lấy. VD: agg_brand,agg_category. Có thể chỉ định size: agg_brand:10 (mặc định 7). Giá trị hỗ trợ: agg_brand, agg_category, agg_string_facet, agg_product_option.
sorterintegerKhôngMã sắp xếp (xem bảng Sorter bên dưới).
pageintegerKhôngTrang hiện tại. Mặc định là 1; giá trị không phải số hoặc nhỏ hơn 1 được coi là 1. Chỉ duyệt được 10.000 kết quả đầu (page × limit ≤ 10.000): trang xa hơn trả items: [] (vẫn có total, aggs), không báo lỗi. Cần nhiều hơn thì thu hẹp bằng bộ lọc.
limitintegerKhôngSố kết quả mỗi trang. Mặc định và tối đa là 50 (giá trị âm / lớn hơn 50 dùng 50).
with_attachmentintegerKhông1: Bao gồm sản phẩm đính kèm; 0: Ẩn (Mặc định).

Request Body

TênKiểuBắt buộcMô tả
string_facetarrayKhôngLọc theo thuộc tính động dạng chuỗi (string facet). Mỗi phần tử có dạng \{"name": "Chất liệu", "value": ["Cotton", "Lụa"]\}.

Sorter

Giá trịMô tả
1 (hoặc không truyền)Mặc định: có keyword thì theo độ liên quan; không có thì theo sản phẩm mới nhất (và thứ tự trong danh mục khi có category_id).
3Giá tăng dần
5Giá giảm dần
7Phần trăm giảm giá giảm dần
9Mới nhất
11Cũ nhất
13Tên A → Z
15Tên Z → A
17Điểm đánh giá tăng dần
19Điểm đánh giá giảm dần
21Số lượt đánh giá tăng dần
23Số lượt đánh giá giảm dần

Response Schema

HTTP 200 - JSON Object

{
  "total": 100,
  "currentpage": 1,
  "limit": 50,
  "items": [
    {
      "id": 10,
      "name": "Iphone 15 Pro Max",
      "type": 1,
      "status": 3,
      "seo_url": "iphone-15-pro-max",
      "brand_id": 5,
      "badge": "Mới",
      "category": {
        "id": 1,
        "name": "Điện thoại",
        "seo_url": "dien-thoai",
        "parent_id": 0
      },
      "selectable_options": [],
      "variants": [],
      "thumbnails": [],
      "gallery": [],
      "social_videos": [],
      "product_uoms": [],
      "info_promotion_note": "Giảm 10%",
      "avg_rating": 4.5,
      "count_rating": 100,
      "default_variant_id": 100,
      "weight_type": 0,
      "weight_sale_mode": 0,
      "pricing_type": 0,
      "procurement_type": 0,
      "allow_preorder": 0,
      "sell_on_zero": 0,
      "_score": 1.5
    }
  ],
  "aggs": [
    {
      "type": "agg_brand",
      "name": "agg_brand",
      "display_order": 1,
      "count_other": 0,
      "stats_bucket": 0,
      "buckets": [
        {
          "id": 50,
          "count": 10,
          "name": "Samsung",
          "more_info": "{\"seo_url\": \"...\"}"
        }
      ]
    }
  ]
}

Response Fields

TrườngKiểuMô tả
totalintegerTổng số kết quả tìm được
currentpageintegerTrang hiện tại
limitintegerSố kết quả mỗi trang
itemsarrayDanh sách sản phẩm. Xem Product Object (chỉ bao gồm các trường Listing)
aggsarrayDanh sách Aggregation (Facets). Xem Aggregation Schema

Aggregation Schema

Mỗi item trong aggs chứa kết quả thống kê cho một loại aggregation.

TrườngKiểuMô tả
typestringLoại aggregation (agg_brand, agg_category, agg_string_facet, agg_product_option)
namestringTên aggregation. Với agg_string_facet và agg_product_option, đây là tên thuộc tính (VD: "Chất liệu")
display_orderintegerThứ tự hiển thị
count_otherintegerSố lượng kết quả nằm ngoài top N (overflow)
stats_bucketinteger/objectThông tin thống kê bucket (min/max cho khoảng giá...)
bucketsarrayDanh sách giá trị. Xem bảng Bucket bên dưới

Bucket Item

TrườngKiểuMô tả
idstring/integerID của giá trị (Category ID, Brand ID, hoặc tên thuộc tính)
countintegerSố lượng sản phẩm khớp
namestringTên hiển thị (tự enrich từ DB cho agg_category và agg_brand)
more_infostringJSON chứa thông tin bổ sung (VD: seo_url cho category)

Aggregation Types

TypeMô tảEnrichment
agg_categoryThống kê theo danh mụcname = tên danh mục, more_info chứa seo_url
agg_brandThống kê theo thương hiệuname = tên thương hiệu
agg_string_facetThống kê theo thuộc tính động (chuỗi)name = giá trị thuộc tính
agg_product_optionThống kê theo product optionname = giá trị option

Các lỗi thường gặp

HTTPMã lỗiMô tả
503error_search_unavailableTìm kiếm tạm thời không thực hiện được. Thử lại sau; nếu lặp lại, liên hệ hỗ trợ. Phản hồi không kèm chi tiết kỹ thuật.

Shop chưa có sản phẩm nào không phải lỗi: trả total: 0, items: []. Tham số phân trang lạ (trang quá xa, số quá lớn) cũng không phải lỗi (xem page ở trên).

Xem Product Object Schema · Variant Object Schema

On this page