2

我正在为 MongoDB 设计一个模式并且有一个问题。这是我需要保存的文档示例:

Product {
  "_id" : ObjectID("..."),
  "name" : "MyProduct",
  "category" : {Catid:ObjectID(".."), name: "Eletronic"}

}

这个“类别”指的是另一个包含所有类别的集合......我将“名称”保存在产品中,因为我在找到产品时需要类别的名称......

但是这个类别的名称需要翻译..

这个怎么设计??

4

3 回答 3

2

我建议将类别(或多个类别)存储为产品中的标识符,而不是进行非规范化。由于您通常会有一个应用程序/中间层/Web 服务器对 MongoDB 进行查询,因此为类别及其在内存中的翻译应用一个简单的缓存层是合理的(您甚至不需要缓存它们很长,如果这很重要)。

Product {
  "_id" : ObjectID("..."),
  "name" : "MyProduct",
  "category" : ObjectID("..")
}

Category {
  "_id" : ObjectID("..."),
  "en-us" : "cheese",
  "de-de" : "Käse",
  "es-mx" : "queso"
}

或者,可以使用更多结构存储类别以处理区域差异:

Category {
  "_id" : ObjectID("..."),
  "en" : { default: "cheese" }
  "de-de" : { default: "käse", "at": "käse2" }
  "es" : { default: "queso" }
}

如果您执行以下查询:

db.products.find({ price : { $gt: 50.00 }}) 

它返回匹配列表,您可以从匹配的产品文档中收集所有类别,并用于$in快速获取当前语言环境的任何非缓存类别值。因此,您可以通过使用此技术进行查询来最大限度地减少到数据库的额外往返次数。如果您有大量类别要匹配,您可以考虑分批进行。

db.categories.find( { _id : { $in : [array_of_ids] } });

然后,将它们匹配在一起。

于 2013-09-02T19:11:54.593 回答
1

MongoDB(和大多数其他 NoSQL 数据库)不支持关系。这并不意味着您不能在 NoSQL 数据库中定义关系/引用。它只是意味着没有可用的本机查询运算符。

在 MongoDB 中有两种不同的方法可以从另一个文档“引用”另一个文档:

  1. 将引用文档的 ID(通常是 ObjectId)存储为引用文档中的字段。如果您的应用程序知道它必须在哪个集合中查找被引用的文档,那么这是最好的方法。示例:{_id: ObjectId(...),category: ObjectId(...)} <- 参考)。

  2. 在技​​术上不是参考,但在很多情况下,将文档(部分)嵌入到其他文档中是有意义的。请注意,对于 NoSQL 数据库,您的模式的规范化应该较少关注。示例:{_id: ObjectId(...); 类别:{_id:ObjectId(...),名称:“xyz”}}。

于 2013-09-02T17:46:44.583 回答
0

有两种方法可以走。如您所指出的,一种称为“非规范化”,您可以将类别信息(每种语言的名称)保存在产品文档本身中。这样,当您加载产品时,您已经拥有每种语言的名称。您可以像这样为产品建模:

{
    _id: ObjectId(""),
    name: "MyProduct",
    category: {
        Catid: ObjectId(""),
        names: {
           en: "MyCategory",
           es: "...",
           fr: "..."
        }
    }
}

另一种选择是,如果类别名称更改过多或您定期添加语言,则不将名称保存在产品上的类别名称上,而是在需要时对类别的类别集合进行查询。

于 2013-09-02T17:36:34.080 回答