是否可以只定义一次用户模型然后用它来更新数据?在所有示例中,我发现更新都在findOne
回调中。是否可以做类似的事情:
var User = require('../models/user');
module.exports = function (io) {
'use strict';
io.on('connection', function (socket) {
var user = User.findOne({
'_id': socket.request.session.passport.user._id
});
socket.on('save_data', function (data) {
user.update({'data': data});
});
socket.on('remove_data', function () {
user.update({'data': false});
});
});
};
答案 0 :(得分:2)
不幸的是,有很多非常糟糕的例子建议使用.findOne()
,然后修改内容,并使用.save()
提交回数据库。
你真正“应该”做的是:
io.on('connection', function (socket) {
socket.on('save_data', function (data) {
user.update(
{ "_id": socket.request.session.passport.user._id },
{ "$set": { "data": data } },
function(err,result) {
// react to result in callback
}
);
});
socket.on('remove_data', function () {
user.update(
{ "_id": socket.request.session.passport.user._id },
{ "$unset": { "data": "" } },
function(err,result) {
// react to result in callback
}
);
});
});
这些操作是“原子的”,并将根据“修改时的当前状态”更新文档。
除非您使用“版本”考虑添加附加处理,否则任何.findOne()
和.save()
示例都不。即使这样,你也可能遇到问题。
因此,最好使用MongoDB的“本机”更新运算符来更改文档属性和内容,因为它们的设计考虑了对属性的影响(以及仅属性)在更新声明中指定。
当然,这只是通过“设置”或删除它们来“更新”现有文档的属性。
如果您的“文档”实际上并不存在,那么您可以将其修改为:
io.on('connection', function (socket) {
socket.on('save_data', function (data) {
user.update(
{ "_id": socket.request.session.passport.user._id },
{ "$set": { "data": data } },
{ "upsert": true },
function(err,result) {
// react to result in callback
}
);
});
socket.on('remove_data', function () {
user.remove(
{ "_id": socket.request.session.passport.user._id },
function(err,result) {
// react to result in callback
}
);
});
});
第一个.update()
调用使用"upsert"修饰符,该修饰符“创建”一个尚未存在的新文档。 $set
操作中的任何内容也会添加到文档中,或者文档存在的位置会“更新”。典型的会话存储,虽然你可以优化它,但这是另一个问题。
在相反的情况下,.remove()
方法从集合中“删除”整个文档,而不是简单地“删除属性”,这是之前完成的。
因此,根据您的案例实际情况,这是针对数据库进行多次交易的更好方法,可能会在“获取”与其他操作之间发生其他操作。