我在NodeJS/Express/Mongoose/AngularJS工作。我想更新一个名为Lists的集合,它有几个属性,其中一个是一个数组。在下面的代码中,我正在items数组中推入一个新的任务项。一切正常,但是更新函数没有发送回更新后的集合,那么我必须对数据库执行另一个查询。有没有更高效的方法来做到这一点?
NodeJS/Express代码:
exports.addTaskToList = function(req, res) {
var listId = req.params.Id;
var taskId = req.params.TaskId;
Lists.update({_id: listId}, {$push: {items: taskId}}, {safe:true, upsert: true}, function(err, result){
if(err) {
console.log('Error updating todo list. ' + err);
}
else{
console.log(result + ' todo list entry updated - New task added');
Lists.findById(listId).populate('items').exec(function (err, updatedEntry) {
if (err) {
console.log('Unable to retrieve todo list entry.');
}
res.send(JSON.stringify(updatedEntry));
});
}
});
};
此外,数组items是Objectids的数组。这些项在单独的架构中,因此在单独的集合中。有没有可能推入整个对象而不仅仅是它的_id,这样就不会再创建另一个集合了?
update方法不返回更新的文档:
但是,如果我们不需要应用程序中返回的文档,而只是想直接更新数据库中的属性,那么Model#update非常适合我们。
如果您需要更新并返回文档,请考虑以下选项之一:
传统方法:
Lists.findById(listId, function(err, list) {
if (err) {
...
} else {
list.items.push(taskId)
list.save(function(err, list) {
...
});
}
});
较短的方法:
Lists.findByIdAndUpdate(listId, {$push: {items: taskId}}, function(err, list) {
...
});
使用findOneAndUpdate()方法,并在查询参数中将选项用作{“new”:true}
return this.sessionModel
.findOneAndUpdate({user_id: data.user_id}, {$set:{session_id: suuid}}, { "new": true})
.exec()
.then(data=>{
return {
sid: data.session_id
}
})
关于你的最后一个问题:
有没有可能推入整个对象而不仅仅是它的_id,这样就不会再创建另一个集合了?
答案是肯定的。使用Mongoose,您可以很容易地将子文档存储在文档中(此处为子文档上的文档)。只需稍微更改一下模式,就可以将整个item对象(而不仅仅是item_id
)推入列表模式中定义的项目数组中。但是您需要修改您的模式,例如:
var itemSchema = new Schema({
// Your Item schema goes here
task: 'string' // For example
});
var listSchema = new Schema({
// Your list schema goes here
listName: String, // For example...
items: [itemSchema] // Finally include an array of items
});
通过向列表的items
属性添加items
对象,然后保存该列表,您的新项将持久化到列表集合中。例如,
var list = new List({
listName: "Things to do"
});
list.items.push({
task: "Mow the lawn"
});
list.save(function(error, result) {
if (error) // Handle error
console.log(result.list) // Will contain your item instance
});
因此,当您加载列表时,items
属性将预先填充项目数组。
这是因为项不再将其保存为单独的集合。它将作为列表的子文档持久化到列表集合中。