使用 Mongoose 返回更新的集合
Posted
技术标签:
【中文标题】使用 Mongoose 返回更新的集合【英文标题】:Return updated collection with Mongoose 【发布时间】:2014-01-07 04:44:37 【问题描述】:我使用 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 是一个 ObjectId 数组。这些项目位于单独的架构中,因此位于单独的集合中。是否可以推送整个对象而不仅仅是它的 _id,这样就不会创建另一个集合?
【问题讨论】:
考虑将findOneAndUpdate
与 new: true
选项一起使用。它将执行更新并返回更新的对象。 (或将new
设置为false
的未更新对象)
【参考方案1】:
update method不返回更新的文档:
但是,如果我们不需要应用程序中返回的文档,并且 只想直接更新数据库中的属性, 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)
...
);
【讨论】:
是的,但需要注意的是,findByIdAndUpdate
不会运行 pre
、post
和其他模式方法,因此 mySchema.pre('save')
无法使用它。
此外,它不会返回“新”的更新元素,而是“旧”元素。如果您想要实际更新的元素,则必须添加选项 new : true
上面的评论回答了我在这里寻找的问题。【参考方案2】:
关于你的最后一个问题:
是否可以推送整个对象而不仅仅是它的 _id 以便 没有创建另一个集合?
答案是肯定的。您可以使用 Mongoose (documentation on sub-documents here) 在文档中轻松存储子文档。通过稍微更改架构,您可以将整个项目对象(不仅仅是项目_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
);
通过将item
对象添加到列表的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
属性将预先填充您的项目数组。
这是因为 Items 将不再将其保存为单独的集合。它将作为 List 的子文档保存到 List 集合中。
【讨论】:
谢谢布兰查德先生(说法语??)。我已经看到了这个,但我想知道如何有效地检索一个项目。我这样做的方式非常方便,因为有一个生成的_id,我不想自己打扰它。我需要更多地探索这条途径,谢谢。 该文档回答了我的问题:“每个文档都有一个 _id。DocumentArrays 有一个特殊的 id 方法可以通过它的 _id 查找文档。”【参考方案3】:使用 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
)
【讨论】:
感谢@Vladimir Marton 的支持。以上是关于使用 Mongoose 返回更新的集合的主要内容,如果未能解决你的问题,请参考以下文章
无法得到我在 nodejs / mongoose / bluebird 中返回的承诺
MongoDB VS MySQL - 为啥 mongo/mongoose 会自动创建数据库和集合?