我正在尝试使用mongoose和MongoDB将任务保存到任务列表中。我想将它冗余地保存在任务集合中,并作为嵌入文档保存在相应的列表文档中。
它运行正常但只有一点:列表的嵌入文档没有它们的objectIds。但是我需要它们以便在逻辑上将它们与tasks-collection中的文档连接起来。
我的架构:
var TaskSchema = new Schema({
_id: ObjectId,
title: String,
list: ObjectId
});
var Task = mongoose.model('task', TaskSchema);
var ListSchema = new Schema({
_id: ObjectId,
title: String,
tasks: [Task.schema]
});
var List = mongoose.model('list', ListSchema);
我的控制器/路由器:
app.post('/lists/:list_id/tasks', function(req, res) {
var listId = req.params.list_id;
// 1. Save the new task into the tasks-collection.
var newTask = new Task();
newTask.title = req.body.title;
newTask.list = listId;
console.log('TaskId:' + newTask._id); // Returns undefined on the console!!!
newTask.save(); // Works fine!
// 2. Add the new task to the coresponding list.
list.findById(listId, function(err, doc){
doc.tasks.push(newTask);
doc.save(); // Saves the new task in the list but WITHOUT its objectId
});
res.redirect('/lists/' + listId)
});
我能以不同的方式使用mongoose吗?或者我是否必须保存任务,然后在将其保存到列表中之前进行查询?
感谢您的建议: - )
答案 0 :(得分:9)
我使用名为populate的强大功能解决了这个问题!
dtryon也是对的:你不需要在你的模型中声明你的_id ObjectIds,它们无论如何都会被添加。你必须嵌套这些东西,因为你的任务被异步保存,所以你必须确保在其他东西之前运行。
以下是解决方案:
架构:
var TaskSchema = new Schema({
title: String,
list: { type: Schema.ObjectId, ref: 'list' }
});
var Task = mongoose.model('task', TaskSchema);
var ListSchema = new Schema({
title: String,
tasks: [{ type: Schema.ObjectId, ref: 'task' }]
});
var List = mongoose.model('list', ListSchema);
控制器/路由器:
app.post('/lists/:list_id/tasks', function(req, res) {
var listId = req.params.list_id;
var newTask = new Task();
newTask.title = req.body.title;
newTask.list = listId;
// WHEN SAVING, WRAP THE REST OF THE CODE
newTask.save(function (err){
if (err) {
console.log('error saving new task');
console.log(err);
} else {
console.log('new task saved successfully');
list.findById(listId), function(err, doc){
doc.tasks.push(newTask);
doc.save(function (err){
if (err) {
console.log('error adding new task to list');
console.log(err);
} else {
console.log('new task saved successfully');
res.redirect('/lists/' + listId);
}
});
});
});
});
});
现在它正确引用,并且使用填充功能,您可以非常舒适地访问条目。像魅力一样工作: - )
答案 1 :(得分:1)
我认为这可能与异步有关。您可能没有看到ObjectId,因为在推送list.findById
之前,您可能正在调用newTask
。此外,在异步操作之外执行res.redirect
也会遇到麻烦。
试试这个:
app.post('/lists/:list_id/tasks', function(req, res) {
var listId = req.params.list_id;
// 1. Save the new task into the tasks-collection.
var newTask = new Task();
newTask.title = req.body.title;
newTask.list = listId;
console.log('TaskId:' + newTask._id); // Returns undefined on the console!!!
// WHEN SAVING, WRAP THE REST OF THE CODE
newTask.save(function (err){
if (err) {
console.log(err);
// do something
}
// 2. Add the new task to the coresponding list.
list.findById(listId, function(err, doc){
doc.tasks.push(newTask);
doc.save(); // Saves the new task in the list but WITHOUT its objectId
// REDIRECT AFTER SUCCESS
res.redirect('/lists/' + listId)
});
});
});