【问题标题】:How to set user and save it with Mongoose?如何设置用户并使用 Mongoose 保存?
【发布时间】:2015-07-13 07:44:29
【问题描述】:

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

【问题讨论】:

    标签: node.js mongodb mongoose socket.io


    【解决方案1】:

    不幸的是,有“很多”非常糟糕的示例建议使用.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() 方法实际上是从集合中“删除”整个文档,而不是像之前所做的那样简单地“删除一个属性”。

    因此,根据您的实际情况,这是针对数据库的多个事务的更好方法,可能会在您的“获取”和其他操作“之间”发生其他操作。

    【讨论】:

      猜你喜欢
      • 2021-06-15
      • 1970-01-01
      • 2013-11-01
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 2015-02-01
      • 1970-01-01
      • 2021-04-03
      相关资源
      最近更新 更多