Nếu sử dụng Mongoose để lưu Products thì đây là cách chuẩn nhất cho app TMĐT | DESIGNING AN E-COMMERCE WEBSITE ALICONCON #3

Nội dung bài viết

Video học lập trình mỗi ngày

DESIGNING AN E-COMMERCE WEBSITE - Ở bài trước chúng ta đã gửi OTP cho mỗi khách hàng đăng ký thành viên trong ứng dụng aliconcon. Giờ đây chúng ta sẽ phân tích về thiết kế cho Products, Orders và Inventories.

Schema model Products in e-COMMERCE mongoose

Trước tiên chúng ta đi phân tích một app e-COMMERCE ( ứng dụng TMĐT ) về Products. Một ứng dụng bán hàng đương nhiên phải có nhiều sản phẩm, mỗi sản phẩm đều nằm trong một category. Do đó, sản phẩm rất đa dạng và phong phú, như là Cameras, Books, Movies, hay Mobiles. Cho nên mỗi sản phẩm đều có những đặc điểm khác nhau, việc lưu trữ không đúng trong database của mỗi sản phẩm như vậy sẽ khó khăn trong quá trình hiển thị, tìm kiếm, create index trong database.

Thông thường các bạn sẽ nghĩ ngay đến việc mỗi categorites sẽ có một collection riêng cho chúng. Ví dụ, tôi thiết kế cho collection Cameras như sau:

{
    "_id": ObjectId("62a17a9edc2048a3b9eb654c"),
    "GTIN": 'CAMERA-0001',
    "name": "X7800",
    "brand": "Cannon",
    "description": "The mamera with the highest resolution",
    "release_date": ISODate("2022-06-09T04:44:14.544Z"),
    "resolution_Mp": 36,
    "technology": "ANS-3000",
    "weight_g": 365,
    "height": 98,
    "width": 125,
    "depth": 70,
    "video_resolution": "1920 x 1080"
}
...
{
    "_id": ObjectId("62a17a9edc2048a3b9eb654d"),
    "GTIN": 'CAMERA-0002',
    ...
}

Tiếp theo tôi thiết kế cho collection , schema model Books như sau:

{
    "_id": ObjectId("62a17a9edc2048a3b9eb654d"),
    "ISBN": "NGK-12345",
    "name": "Nha gia kim",
    "editor": "Amazon",
    "description": "A book to understand about me",
    "release_date": ISODate("2022-06-09T04:44:14.544Z"),
    "weight_g": 365,
    "author": "Paulo Coelho",
    "pages": 100
},
{
    "_id": ObjectId("62a17a9edc2048a3b9eb654e"),
    "ISBN": "NGK-12346",
    ...
}

Thoạt nhìn có vẻ như nó hoản hảo. Nhưng điều gì xảy ra nếu chúng ta cho chúng hiển thị cả hai dữ liệu đó trên cùng một page. Hay thực tế là Lịch sử người dùng xem hàng. Cho nên cách này không ổn chút nào, chúng ta đi xem xét cách tiếp theo.

Polymorphic model mongoose

Rõ ràng cách trên không phù hợp cho việc thiết kế một schema products trong e-Commerce. Cho nên việc cần làm nếu bạn là một backend chính gốc thì làm sao đưa tất cả về một collection mà thôi. Trong Mongodb có tất cả 13 mẫu thiết kế cho chúng ta chọn lựa. Và có vẻ Polymorphic model nghe có vẻ phù hợp. Hay xem xét mẫu này thế nào.

Như trên thì điều kiện chúng ta phải lưu trữ tất cả Products trong một collection. Ngoài ra, phải thông minh trong việc đặt các tên trường trong schema vì mỗi sản phẩm đều có một đặc điểm riêng. Hãy xem xét cách làm sau:

{
    "_id": ObjectId("62a17a9edc2048a3b9eb654c"),
    "code": 'CAMERA-0001',
    "name": "X7800",
    "brand": "Cannon",
    "description": "The mamera with the highest resolution",
    "release_date": ISODate("2022-06-09T04:44:14.544Z"),
    "weight_g": 365
},
{
    "_id": ObjectId("62a17a9edc2048a3b9eb654d"),
    "code": "NGK-12345",
    "name": "Nha gia kim",
    "brand": "Amazon",
    "description": "A book to understand about me",
    "release_date": ISODate("2022-06-09T04:44:14.544Z"),
    "weight_g": 365
},

Nhìn vào sẽ thấy trong một structure document sẽ thấy một số fields chung trong tất cả các sản phẩm của CamerasBooks, như là sku, code, name, brand... Và một số fields khác, vậy lưu chúng như thế nào? Xem xét thêm, tôi sẽ add một field specs vào mỗi document, và trong đó chứa những fields còn lại như sau:

{
    "_id": ObjectId("62a17a9edc2048a3b9eb654c"),
    "code": 'CAMERA-0001',
    "name": "X7800",
    "brand": "Cannon",
    "description": "The mamera with the highest resolution",
    "release_date": ISODate("2022-06-09T04:44:14.544Z"),
    "weight_g": 365,
    "specs": [
        {"resolution_Mp": 36},
        {"technology": "ANS-3000"},
        {"height": 98},
        {"width": 125},
        {"depth": 70},
        {"video_resolution": "1920 x 1080"}
        ...
    ]
},
{
    "_id": ObjectId("62a17a9edc2048a3b9eb654d"),
    "code": "NGK-12345",
    "name": "Nha gia kim",
    "brand": "Amazon",
    "description": "A book to understand about me",
    "release_date": ISODate("2022-06-09T04:44:14.544Z"),
    "weight_g": 365,
    "specs": [
        {"author": "Paulo Coelho"},
        {"editor": "Amazon"},
        {"pages": 100}
        ...
    ]
},

Đó chính là Polymorphic model mà chúng ta muốn áp dụng, mô hình này giúp bạn có thể lưu trữ đa hình các sản phẩm một cách dễ dàng. Đương nhiên mọi thứ đều có hai mặt, ưu và nhược.

Pros and cons of the Polymorphic model

Sau đây chúng ta nói về ưu và nhược của phương pháp này một chút trước khi tôi và bạn đi đến cách cuối cùng, và cách đó có vẻ vẹn toàn hơn.

  • Ưu: Dễ dàng thực hiện việc lưu trữ, ngoài ra dễ dàng hiện thị các sản phẩm trên một trang.
  • Nhược: Khó khăn vì dữ diệu không đồng nhất.

Cách tốt nhất để store products

Như vậy chúng ta đã biết các tổ chức dữ liệu cho products một cách khoa học cho dù có nhiều loại sản phẩm đi chăng nữa. Nhưng nếu tinh ý bạn sẽ nhận ra rằng, rất khó để tìm kiếm một properties trong một sản phẩm. Ví dụ :

{
    "_id": ObjectId("62a17a9edc2048a3b9eb654c"),
    "code": 'CAMERA-0001',
    "name": "X7800",
    "brand": "Cannon",
    "description": "The mamera with the highest resolution",
    "release_date": ISODate("2022-06-09T04:44:14.544Z"),
    "weight_g": 365,
    "specs": [
        {"resolution_Mp": 36},
        {"technology": "ANS-3000"},
        {"height": 98},
        {"width": 125},
        {"depth": 70},
        {"video_resolution": "1920 x 1080"}
        ...
    ]
},

Chúng ta muốn tìm kiếm specs.resolution_Mp or specs.technology ... và nhiều hơn nữa thì chúng ta phải tạo index cho điều này. Nếu mà như vậy thì có lẽ sẽ không bao giờ bạn có thể tạo index đầy đủ, vì vô số thuộc tính được tạo ra từ products trong tương lai. Đừng lo lắng tôi sẽ giúp bạn. Hãy cố gắng xem tiếp dưới đây.

Để hoàn chỉnh một shema Products thì Polymorphic model là chưa đủ. Háy xem xét thêm môt pattern mới của Mongodb đó là Attribute model.

{
    "_id": ObjectId("62a17a9edc2048a3b9eb654c"),
    "code": 'CAMERA-0001',
    "name": "X7800",
    "brand": "Cannon",
    "description": "The mamera with the highest resolution",
    "release_date": ISODate("2022-06-09T04:44:14.544Z"),
    "weight_g": 365,
    "specs": [
        {k: "resolution_Mp", v: 36, u: "mp"},
        {k: "technology", v: "ANS-3000"},
        {K: "height", v: 98},
        {k: "width", v: 125},
        {k: "depth", v: 70},
        {k: "video_resolution", v: "1920 x 1080"}
        ...
    ]
},
{
    "_id": ObjectId("62a17a9edc2048a3b9eb654d"),
    "code": "NGK-12345",
    "name": "Nha gia kim",
    "brand": "Amazon",
    "description": "A book to understand about me",
    "release_date": ISODate("2022-06-09T04:44:14.544Z"),
    "weight_g": 365,
    "specs": [
        {k: "author", v: "Paulo Coelho"},
        {k: "editor"m v: "Amazon"},
        {k: "pages", v: 100}
        ...
    ]
},

Tôi sẽ thay thế tất cả các thuộc tính trong specs bằng cách sử dụng {k,v ...} Sau khi thao tác xong thì đánh index lại như sau:

shema.createIndexes({ "specs.k": 1, "specs.v": 1})

Quá tuyệt vời khi chúng ta chi mất 2 index, và sau này khi hệ thống được mở rộng với nhiều thuộc tính thì chúng ta cũng không cần làm gì nữa... Rất ok đúng không anh em.

Đón xem phần tiếp theo ... Cách thiết kế đặt đơn hàng và hàng tồn kho.

Có thể bạn đã bị missing