如何设置用户并使用Mongoose保存它?

时间:2015-07-13 07:44:29

标签: node.js mongodb mongoose socket.io

是否可以只定义一次用户模型然后用它来更新数据?在所有示例中,我发现更新都在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});
        });
    });
};

1 个答案:

答案 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
               }
           );
        });
    });

$set$unset同时对文档的“数据”属性起作用。

这些操作是“原子的”,并将根据“修改时的当前状态”更新文档。

除非您使用“版本”考虑添加附加处理,否则任何.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()方法从集合中“删除”整个文档,而不是简单地“删除属性”,这是之前完成的。

因此,根据您的案例实际情况,这是针对数据库进行多次交易的更好方法,可能会在“获取”与其他操作之间发生其他操作。