【问题标题】:Nested or different mongodb collections for e-commerce products with multi language?多语言电子商务产品的嵌套或不同的mongodb集合?
【发布时间】:2021-12-26 10:22:52
【问题描述】:

他在那里,我曾经与 Relational DBS 合作,但现在正在尝试实现电子商务商店并使用 mongodb。

我需要产品、子产品和描述(多语言);

我更喜欢用 3 个集合分隔所有内容(这可能不是一个好主意,因为 mongo 对一个实体使用 1 个集合,在我的示例中,1 个实体使用 3 个集合)

"content": [{
        pid: 1,
        lang: "ru",
        title: "Привет"
    },
    {
        pid: 1,
        lang: "en",
        title: "Hello"
    },
    {
        pid: 2,
        lang: "ru",
        title: "Пока"
    },
    {
        pid: 2,
        lang: "en",
        title: "Bye"
    }
],
"products": [{
        "_id": 1,
        "item": "almonds",
        "price": 12,
    },
    {
        "_id": 2,
        "item": "pecans",
        "price": 20,
    },
],
"sub": [{
        "_id": 11,
        "pid": 1,
        "features": {
            "color": ["red"],
            "size": 42
        },
        "qt": 5
    },
    {
        "_id": 12,
        "pid": 1,
        "features": {
            "color": ["red"],
            "size": 43
        },
        "qt": 2
    },
    {
        "_id": 13,
        "pid": 1,
        "features": {
            "color": ["yellow"],
            "size": 44
        },
        "qt": 3
    },
    {
        "_id": 21,
        "pid": 2,
        "features": {
            "color": ["yellow"],
            "size": 41
        },
        "qt": 6
    },
    {
        "_id": 22,
        "pid": 2,
        "features": {
            "color": ["red"],
            "size": 47
        },
        "qt": 10
    }
]

产品应该有子产品才能使用过滤器,例如,当我想过滤项目时,我会在子产品集合中查找所有黄色 t-short,例如尺寸为 44,然后我只需 $groupproductId的项目和主产品一起制作$lookup并退货。

另外,为了接收带有描述的主要产品,我应该使用content 收集$lookup

这是个好主意还是我应该为productcontent 使用1 个集合?

喜欢:

"products": [{
        "_id": 1,
        "item": "almonds",
        "price": 12,
        "content": [{
                lang: "ru",
                title: "Привет"
            },
            {
                lang: "en",
                title: "Hello"
            },
        },
    ]

也许我应该在主要产品中也包含子项目,例如:

"products": [{
        "_id": 1,
        "item": "almonds",
        "price": 12,
        "content": [{
                lang: "ru",
                title: "Привет"
            },
            {
                lang: "en",
                title: "Hello"
            },
        },
        "sub": [{
                "features": {
                    "color": ["red"],
                    "size": 42
                },
                "qt": 5
            },
            {
                "features": {
                    "color": ["red"],
                    "size": 43
                },
                "qt": 2
            },

        ]
    ]

主要问题是比较所有内容而不关心集合的大小是个好主意吗?如果是这样,我应该如何对嵌套文档('sub-products')进行过滤(以前的'sub-products'集合就像一个普通集合,我可以进行聚合以便按颜色查找所有项目,例如:@987654332 @嵌套文档如何管理,又不会被压垮操作?

【问题讨论】:

  • MongoDB 数据建模是一个涉及多个方面的过程 - 包括实体之间的关系、数据的大小、每条记录中的数据大小、您要执行的重要 CRUD / 查询操作等。 MongoDB文档的最大大小为 16 MB,这允许文档中的非规范化数据。另请参阅:Data Modeling Introduction.

标签: javascript database mongodb database-design architecture


【解决方案1】:

您关于如何拆分实体/文档的数据模型设计决策的问题仅凭所提供的信息无法以有用的方式得到解答,但我可以为您提供一些方面的决策考虑。

MongoDb 是一种键值对存储,因此如果您可以以一种主要使用基于键的查找的方式设计数据,那么它是最有用的。这可以通过在 _id 以外的文档字段上创建额外的索引来扩展,默认情况下它是索引的。未编入索引的所有内容都将导致 collection scans 并且查询效率非常低。索引可以大大增加所需的存储量,因此根据您的方案成本可能是禁止仅索引您以后要查询的每个字段的因素。这意味着在设计实体时,您还必须考虑集合的估计大小和集合之间引用的可能性(例如通过 guid)。

因此,为了为您的数据模型做出正确的设计决策,我们不能仅根据您要存储的数据架构进行判断,而是根据您希望稍后执行的查询以及预期的集合大小/未来扩展来判断要求。这些是您在问题中只涉及非常轻微的方面。例如,如果您计划查询所有实体中所有类型的复杂连接和属性值组合,您可能会问自己是否可以负担非规范化数据和附加索引的额外存储成本,或者传统(或现代) SQL-RDB,或者图形数据库可能比键值存储更适合您的用例。然而,如果您的数据库规模一直都很小,而您主要关心的是开发人员的工作效率,那么这些考虑可能毫无价值。

您可以通过使用elemmatch 来回答有关在父“产品”数组中访问“子”文档的具体问题。例如:

db.products.find({sub: {$elemMatch: {'features.size':43, 'features.color':'red'}}})

请再次注意,这些查询只有在您为查询中的字段编制索引时才会有效。如果是数组子文档,则意味着查看multi-key indexes.

为了获得更多知识,以便更好地围绕 DB 模型做出决策以及您对 MongoDB 中的查询的问题,我建议阅读 official MongoDB data model design guidedocumentation for querying arrays,并在谷歌上搜索一些关于规范化和 SQL vs noSQL 动机的文章就scaling/shardingACIDeventual consistency而言。

【讨论】:

  • 感谢有用的链接和一些线索
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-07
  • 1970-01-01
  • 2011-10-07
  • 2019-02-22
  • 2012-05-06
  • 1970-01-01
相关资源
最近更新 更多