【问题标题】:Best practices for structuring hierarchical/classified data in mongodb在 mongodb 中构建分层/分类数据的最佳实践
【发布时间】:2021-05-28 23:28:15
【问题描述】:

总结:

我正在构建我的第一个大型全栈应用程序(MERN 栈),它试图模仿一家大型服装店。每件衣服都有很多“标签”,代表它的特点,上衣/下装/配饰/鞋子/等,以及子类别,例如在顶部有衬衫/外套/运动衫/等,以及其中的子子类别,例如在衬衫上有衬衫/T 恤/等。每篇文章都有原色、底边、口袋、技术特征的标签,不胜枚举。

主要问题:

我应该如何最好地使用 mongoose 模式组织 mongodb 中的数据,以便在我计划拥有 50,000 篇或更多文章时快速搜索它?真的很好奇,当商品具有如此多的识别特征时,大型服装零售商通常如何设计数据库以便客户轻松搜索?

我尝试或想到的事情:

在 mongoDB 网站上,建议使用带有子引用的树结构。这里是链接:https://docs.mongodb.com/manual/tutorial/model-tree-structures-with-child-references/ 我喜欢这个想法,但我在这里读到:https://developer.mongodb.com/article/mongodb-schema-design-best-practices/ 当存储超过几千条数据时,使用对象 ID 引用不再足够,并且可能由于数据限制而产生问题。

此外,每件衣服都会落入树的许多不同部分。例如,它可能是一件衬衫,所以它会在树的衬衫“叶子”中,然后如果它是蓝色的,它将在树的蓝色“叶子”中,如果它是可持续采购的,它会掉下来也进入那棵树的“叶子”。考虑到这一点,树状数据结构似乎不是正确的方法。它将在许多不同的叶子中存储相同的 ObjectID。

我的另一个想法是将文章信息(描述、价格和图片)与标签/层次信息分开存储。然后每个标记对象都会有一个对该项目的 ObjectID 引用。这样,如果我想收集这些信息,我可以利用 mongoose 的 propogate 方法。

我还创建了大树结构的一部分,作为我所拥有的设计理念的概念证明,目前这仅适用于前端,但这也会造成不良搜索,因为它们看起来像分类法[0] .options[0].options[0].options[0].title 到 'blouse'。从我的课程来看,这似乎不是使代码可读的好方法。这只是一个 long long 分支对象的 sn-p。我打算尝试使它成为一个猫鼬模式。但它的工作量很大,我想确保我做得很好。

 const taxonomy = [
    {
        title: 'Category',
        selected: false,
        options: [
            {
                title: 'top',
                selected: false,
                options: [
                    {
                        title: 'Shirt',
                        selected: false,
                        options: [
                            {
                                title: 'Blouse',
                                selected: false,
                            },
                            {
                                title: 'polo',
                                selected: false,
                            },
                            {
                                title: 'button down',
                                selected: false,
                            },
                        ],
                    },
                    {
                        title: 'T-Shirt',
                        selected: false,
                    },
                    {
                        title: 'Sweater',
                        selected: false,
                    },
                    {
                        title: 'Sweatshirt and hoodie',
                        selected: false,
                    },
                ],
            },

前进:

我不是在寻找一个完美的答案,但我确信以前有人已经解决过这个问题(所有销售大量分类产品的大企业都有)如果有人能指出我正确的方向,例如,给我给谷歌一些条款,一些文章要阅读,或者一些视频要观看,那就太好了。

感谢您提供的任何指导。

【问题讨论】:

    标签: node.js mongodb express mongoose mongoose-schema


    【解决方案1】:

    MongoDB 是一个基于文档的数据库。集合中的每条记录都是一个文档,并且每个文档都应该是自包含的(它应该包含您在其中需要的所有信息)。

    最佳做法是为您能想到的每个逻辑整体创建一个集合。当您拥有包含大量数据的文档时,这是最佳做法,因为它是可扩展的。

    例如,您应该为以下对象创建集合:ProductsSubproductsCategoriesItemsProvidersDiscounts...

    现在,当您创建架构时,您可以将一个集合文档的引用存储为另一个集合文档的属性,而不是创建嵌套结构。

    注意:最大文档大小为 16 兆字节。

    不良做法

    让我们首先看看什么是不好的做法。考虑这个结构:

    Product = {
      "name": "Product_name",
      "sub_products": [{
          "sub_product_name": "Subpoduct_name_1",
          "sub_product_description": "Description",
          "items": [{
              "item_name": "item_name_1",
              "item_desciption": "Description",
              "discounts": [{
                "discount_name": "Discount_1",
                "percentage": 25
              }]
            },
            {
              "item_name": "item_name_2",
              "item_desciption": "Description",
              "discounts": [{
                "discount_name": "Discount_1",
                "percentage": 25
              },
              {
                "discount_name": "Discount_2",
                "percentage": 50
              }]
            },
          ]
        },
        ...
      ]
    }
    

    这里product 文档有sub_products 属性,它是sub_products 的数组。每个sub_productitems,每个itemdiscounts。如您所见,由于这种嵌套结构,很快就会超过最大文档大小。

    良好做法

    考虑这个结构:

    Product = {
      "name": "Product_name",
      "sub_products": [
         'sub_product_1_id',
         'sub_product_2_id',
         'sub_product_3_id',
         'sub_product_4_id',
         'sub_product_5_id',
         ...
      ]
    }
    
    Subproduct = {
      "id": "sub_product_1_id",
      "sub_product_name": "Subroduct_name",
      "sub_product_description": "Description",
      "items": [
         'item_1_id',
         'item_2_id',
         'item_3_id',
         'item_4_id',
         'item_5_id',
         ...
      ]
    }
    
    Item = {
        "id": "item_1_id",
      "item_name": "item_name_1",
      "item_desciption": "Description",
      "items": [
         'discount_1_id',
         'discount_2_id',
         'discount_3_id',
         'discount_4_id',
         'discount_5_id',
         ...
      ]
    }
    
    Discount = {
      "id": "discount_1_id",
      "discount_name": "Discount_1",
      "percentage": 25
    }
    

    现在,您拥有每个逻辑整体的集合,您只是将一个集合文档的引用存储为另一个集合文档的属性。

    现在您可以使用Mongoose 的最佳功能之一,即人口。如果您将一个集合文档的引用存储为另一个集合文档的属性,则在执行数据库查询时,Mongoose 会将引用替换为实际文档。

    【讨论】:

    • 谢谢一百万。非常感谢您的帮助。
    • 欢迎。如果对您有帮助,还可以考虑投票并接受我的回答。
    猜你喜欢
    • 1970-01-01
    • 2015-01-13
    • 1970-01-01
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    相关资源
    最近更新 更多