我正在为MongoDB设计一个架构,并有一个问题。这是我需要保存的文档示例:
Product {
"_id" : ObjectID("..."),
"name" : "MyProduct",
"category" : {Catid:ObjectID(".."), name: "Eletronic"}
}
此“类别”指的是具有所有类别的另一个集合...我在产品中保存了“名称”,因为当我找到产品时我需要该类别的名称..
但是这个类别的名称需要翻译..
我是如何设计的?
答案 0 :(得分: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] } });
然后,将它们匹配在一起。
答案 1 :(得分:1)
MongoDB(以及大多数其他NoSQL数据库)不支持关系。 这并不意味着您无法在NoSQL数据库中定义关系/引用。它只是意味着没有可用的本机查询运算符。
有两种不同的方法可以在MongoDB中“引用”另一个文档:
将引用文档的ID(通常是ObjectId)存储为引用文档中的字段。如果您的应用程序知道必须查找引用文档的集合,这是最佳方法。示例:{_ id:ObjectId(...),category:ObjectId(...)}< - reference)。
从技术上讲,它不是一个参考,但在很多情况下,将(部分)文档嵌入到其他文档中是有意义的。请注意,使用NoSQL数据库时,模式的规范化应该不那么重要。示例:{_ id:ObjectId(...);类别:{_ id:ObjectId(...),名称:“xyz”}}。
答案 2 :(得分:0)
你有两种方法可以去。正如您所指出的那样,其中一个称为“非规范化”,您可以在其中保存产品文档本身中的类别信息(每种语言中的名称)。这样,当您加载产品时,您已经拥有每种语言的名称。您可以像这样建模产品:
{
_id: ObjectId(""),
name: "MyProduct",
category: {
Catid: ObjectId(""),
names: {
en: "MyCategory",
es: "...",
fr: "..."
}
}
}
另一个选项是,如果类别名称变化太大或者您经常添加语言,则不是在产品上的类别名称上保存名称,而是在需要时对类别的类别集合进行查询它