javascript - 在 Meteor 中使用复杂的更新选择器进行原子操作

标签 javascript mongodb meteor

假设您正在制作一个聊天室应用程序,用户可以在其中设置昵称,但昵称对于聊天室必须是唯一的。我已经用这样的方法实现了这个:

Meteor.methods({
  setNickname: function( nickname ) {
    check( nickname, String );

    if ( ! this.userId ) { /* throw error */ }

    var chatroom = Chatroom.collection.findOne({
      'users._id': this.userId
    });

    if ( _.findWhere( chatroom.users, { nickname: nickname } ) ) { /* throw error */ }

    Chatroom.collection.update({
      'users._id': this.userId,
    }, {
      $set: {
        'users.$.nickname': nickname
      }
    });
  }
});

这感觉很笨拙,我想知道验证逻辑与这样的查询分离是否可能存在并发问题。我想我可以将此逻辑移动到查询本身中,如下所示:

Meteor.methods({
  setNickname: function( nickname ) {
    check( nickname, String );

    if ( ! this.userId ) { /* throw error */ }

    Chatroom.collection.update({
      'users._id': this.userId,
      'users.nickname': {
        $ne: nickname
      }
    }, {
      $set: {
        'users.$.nickname': nickname
      }
    });
  }
});

我对 MongoDB 相当陌生,所以我不确定哪种方法更好。两种方法似乎工作原理相同,但我觉得如果两个用户尝试同时设置相同的昵称,第一种方法可以允许相同的昵称。

所以基本上,我应该使用复杂的更新选择器来确保此类操作是原子的吗?

最佳答案

一种方法是在 mongodb 中为昵称和聊天室 ID 设置唯一索引。这将防止违反该索引的插入或更新。如果您尝试插入当前存在的昵称,则必须捕获回调中的错误。

http://docs.mongodb.org/manual/tutorial/create-a-unique-index/

关于javascript - 在 Meteor 中使用复杂的更新选择器进行原子操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27031075/

相关文章:

javascript - 如何将数据从mysql数据库发送到JS脚本?

javascript - 嵌套http.request AngularJS后同时显示数据

javascript - $(window).resize 和 $("#foo").scroll 上的触发函数

mysql - mongify 检查database.config 的问题

javascript - Meteor.publish 回调未被调用

ssl - 在 Meteor 中使用 SSL/HTTPS?

javascript - 如何使用旋转找出旋转梯形的边界框

mongodb - MongoDB 中的 find() 和 findOne() 方法显示不同的结果

java - Morphia for Mongo DB 和低性能代码

ubuntu - 在 Windows 机器上从 USB 运行的 ubuntu 13.04 上安装 meteor 失败