Node.js 在mongoose中保存嵌套对象
我来自PHP/MySQL的背景,在构建和保存数据方面,我一直在与最佳实践作斗争 我正在尝试创建一个小应用程序,在其中我可以添加多种成分的食谱。我有一堆预先填充的成分作为种子数据,其模式如下所示:Node.js 在mongoose中保存嵌套对象,node.js,mongodb,express,mongoose,Node.js,Mongodb,Express,Mongoose,我来自PHP/MySQL的背景,在构建和保存数据方面,我一直在与最佳实践作斗争 我正在尝试创建一个小应用程序,在其中我可以添加多种成分的食谱。我有一堆预先填充的成分作为种子数据,其模式如下所示: var IngredientSchema = new Schema({ name: { type: String, trim: true, required: true, index: { unique: t
var IngredientSchema = new Schema({
name: {
type: String,
trim: true,
required: true,
index: {
unique: true
}
},
created: {
type: Date,
default: Date.now
}
});
var Ingredient = mongoose.model('Ingredient', IngredientSchema);
当前的配方如下所示:
var RecipeSchema = new Schema({
name: {
type: String,
trim: true
},
ingredients: [
{
type: Schema.Types.ObjectId,
ref: 'RecipeIngredient'
}
],
created: {
type: Date,
default: Date.now
}
});
var Recipe = mongoose.model('Recipe', RecipeSchema);
最后,我有一个RecipeIngredientSchema。现在,这就是我的MySQL背景可能潜入的地方;我之所以这样做,是因为我想要配方和配料之间的一对多关系,但我也希望能够指定一个单位:
var RecipeIngredientSchema = new Schema({
recipe: {
type: Schema.Types.ObjectId,
ref: 'Recipe'
},
ingredient: {
type: Schema.Types.ObjectId,
ref: 'Ingredient'
},
unit: {
type: Schema.Types.ObjectId,
ref: 'Unit'
},
created: {
type: Date,
default: Date.now
}
});
var RecipeIngredient = mongoose.model('RecipeIngredient', RecipeIngredientSchema);
我的问题分为两部分:
- 在数据建模方面,我是以一种明智的方式进行这项工作,还是偏离了目标
- 保存含有多种成分的配方的过程实际上是什么样的李>
exports.create = function(req, res) {
var recipe = new Recipe(req.body);
recipe.save(function(err, recipe) {
if (err) {
return res.jsonp(err);
} else {
// Loop ingredients
if (req.body.ingredients) {
for(var prop in req.body.ingredients) {
var recipeIngredient = new RecipeIngredient({
recipeId: recipe._id,
ingredientId: mongoose.Types.ObjectId(req.body.ingredients[prop])
});
recipeIngredient.save(function(err, recipeIngredient) {
if (err) {
return res.jsonp(err);
} else {
recipe.recipeIngredients.push(recipeIngredient._id);
recipe.save(function(err, recipe) {
return res.jsonp(recipe);
});
}
});
};
}
}
});
}
我觉得这是令人费解的,通常是错误的,所以希望能得到一些指导 NoSQL数据库(或通常的文档存储)的优点在于,您不必将数据拆分为多个表/集合。您可以将所有相关数据存储到单个实体中,以便一次完成读取操作
没有这样做的“正确”方法,但是如果你要使用NoSQL,我会考虑把整个配方(配方和配料和方向)保存为一个单一的文档,而不是把数据分割成3个或4个表格,即关系模型。 例如,我将保存一个配方,如下所示:
recipe = {
name: 'name of recipe'
time: '45 minutes'
ingredients : [
{qty: 3, unit: 'item', name: 'tomatoes'},
{qty: 0.5, unit: 'tbs', name: 'salt'},
{qty: 1, name: 'item', name: 'avocado'}
]
}
现在,这不是精灵尘埃。有时,将数据拆分为多个表/集合并使用关系查询语言(如SQL)将有助于查询数据。例如,如果您想查询使用“西红柿”的所有配方,那么使用关系数据库和配方/配料关系的联接表将比NoSQL方法简单得多
这是您需要在某一点上做出的决定:对于您的应用程序,您更适合使用NoSQL还是RBMS?如果要在DB中保存嵌套对象,您有两个选项:作为嵌入模式或使用ref。如果使用ref保存它们,嵌套模式将保存在单独的集合中 开始看这个示例和这个示例,您可以使用“最小化”选项在保存父文档时自动保存子文档
const UserSchema = new mongoose.Schema({
name : String,
email : String,
},{
minimize : true
});
同意。工程师会根据问题选择他们的技术,而不是因为某项技术“趋向”或“更容易”。如果数据是关系型的,那么你就不应该试图在非关系型数据存储上强制使用关系型范例。我考虑过这种方法,但想知道如何对数据进行规范化,以便成分不重复,但也可以有与之相关联的不同单元。我的目标是简单地掌握node/mongodb,而不是创建一个功能齐全的产品,所以我只是在探索我的选择。谢谢你的回答,我来看看结果如何!我不同意你关于“找到所有使用‘西红柿’的食谱”的观点。使用您的示例,您只需执行
recipes.find({'components.name':'tomatos')
。Mongo的读取速度非常快,所以这应该比sql中的连接快得多。因此,关键是我们没有真正规范MongoDB中的数据?