【问题标题】:Create Mongoose Schema Dynamically for e-commerce website in Node在 Node 中为电子商务网站动态创建 Mongoose Schema
【发布时间】:2021-08-24 08:21:29
【问题描述】:

我想问一个关于电子商务数据库设计在可扩展性和灵活性方面的可能解决方案的问题。

我们将在后端使用 MongoDB 和 Node。

我附上了一张图片,供您查看我们目前拥有的内容。我们目前有一个产品表,可用于将产品添加到系统中。有趣的是,我们希望能够将不同类型的产品添加到具有不同属性的系统中。

例如,在管理员管理页面中,我们可以选择一个衣服项,我们应该在其中填写一个包含高度、长度、尺寸等字段的表单 .. . 等等。问题是我们如何在数据库设计中对这种结构方式进行建模?

我们的想法是创建 ClothesProduct 等表,并分别将 Products 表 连接到其中之一。但是对于不同的产品类型,我们可以有 100 个不同的表。我们想从管理员管理中动态添加产品类型。这在猫鼬中可能吗?因为在 Products 表 中创建所有可能的字段效率不高,而且从长远来看会给我们带来沉重打击。

Database design snippet

也许我们应该为每种独特的产品类型创建单独的表格,然后从前端选择其中一个来显示正确的表格?

你能分享一下你的想法吗?

谢谢!

【问题讨论】:

    标签: node.js database mongodb mongoose admin


    【解决方案1】:

    我们有一个 mongoose 后端,我从大约 3 年前成立以来就一直在开发它。这是我的一些经验教训:

    • Mongodb 是 noSQL:通过 ID 链接所有这些对象,查找“Shop A”的所有产品变得非常痛苦:在获取特定商店的产品列表之前,您必须进行多次查询(shop ->品牌类别 -> 子类别 -> 产品)。考虑将某些对象嵌套在其他对象中(例如,类别内的子类别,因为它们在语义上是相同的)。这将节省大量的加载时间。

    • 动态创建产品字段:我们构建了一个(现在)大模块,允许用户创建自己的数据库键和值,并将它们分配给不同的对象。本质上,它看起来像这样:

    SpecialFieldModel: new Schema({
       ...,
        key: String,
        value: String,
       ...,
       
    })
    

    这样,您的用户可以“制作自己的产品”

    • 产品数量:Mongodb 查询可以处理巨大的数据负载,所以我不会太担心某些表存在数千个对象。但是,如果您想要关于所有数据的大型报告,则需要确保您的 ID 位于正确的位置。然后,您可以使用Aggregation framework 构建可能必须将数据库中的多个收集器绑定在一起的大查询,并以有效的方式获取数据。

    • 不要双向引用 ID,除非您不知道自己在做什么:在子类别中保存对类别 ID 的引用,反之亦然,这非常令人困惑。如果要切换子类别,您必须更新哪个字段?非此即彼?或两者?即使有强大的测试,对于新开发人员来说,理解“查询运行的方向”也可能会非常混乱(如果您正在构建一个可能需要在未来扩展的产品)。我们已经完成了这两项工作,这导致了一些问题。但是,我发现那些保存了对上层对象(而不是下层对象)的引用的模块始终更令人愉快且易于使用。

    • created/updatedAt:考虑将这些字段添加到每个模型和架构中。这将有助于调试、可扩展性和您将来能够构建的一般功能,否则这些功能可能是不可能的。 (ProductSchema.set('timestamps', true);)

    请接受我的建议,因为我还没有设计我们的大部分模块。但这些都是我认为继续致力于我们的应用程序的事情。

    【讨论】:

    • 嗨,Michal,感谢您的回答,我会好好利用它。 :) 我要做的是将上层模型的 ID 存储在下层模型上。例如,我将 categoryID 保留在 SubCategories 中,但从 Categories 中删除 SubCategoryID 数组。请您详细说明动态模式添加,好吗?听起来真的很好,但我不知道从哪里开始。也就是说,您发现这是产品类型分离的最佳解决方案?
    • 对于“自定义架构添加”,我们发现拆分我们的对象效果很好:Product 和 ProductDraft。草稿指定具体对象的外观,可以在其中添加自定义模式,嵌套在草稿中,然后将其转移到具体对象。为什么会有草稿令人困惑,但它基本上允许动态化/用户指定的具体对象。示例:draftSchema: {dynamicField: [{name: String, value: [String]}]} --> 具体:{dynamicField: [{name: "Prod1", value: [String]}]}。我不确定这是否清楚
    • 非常感谢您详细说明您的解决方案。 :) 我只是在想,如果我们在 Product 表中添加一个 customOptions 字段,我们是否可以让它更简单一些,这将是一个键值对数组,我们会为每个产品以不同的方式填充它?
    • 通过 Model.find().populate(...) 填充效率不是很高,并且无法处理来自不同集合的 ID。您可能必须执行类似 [{entity: String, ID: ObjectId("a34fd...")}] 的操作,获取合适的模型,然后再进行搜索。但是,我不能给你一个确切的实施策略:我不知道你的要求、预算、可能的可钻探期限等。
    猜你喜欢
    • 2017-09-07
    • 1970-01-01
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 2016-11-10
    • 1970-01-01
    • 2022-08-16
    • 2011-06-11
    相关资源
    最近更新 更多