nodejs mongodb并发请求save和update

用nodejs发起了并发访问,爬取目标网站的js库,并把js库的数量存到数据库,最后存的代码是这样

jsLib.find({name:value},function(err,data){
             if(data.length!=0){
                        console.log(data);
                        var num = data[0].num+1;
                        jsLib.update({name:value},
                                {
                                    name:value,
                                    num :num
                                }                                                    
                    }else{
                        var jslib = new jsLib({
                                name : value,
                                num : 1
                        })
                        jslib.save();

先查找,如果没有就存,有的话就更新+1
但由于并发太多,导致大量重复数据
clipboard.png

我能想到的一个解决方案是用update的 upsert,但即使用upsert我也要知道他之前的数量是多少,否则没法+1,所以可能不能用

另一个方案是使用触发器,比如数据都写到数组,当数组数据满了后再统一存到数据库,但这样一来要自己写个触发器,大家有其它的解决法方案么?

或者mongodb是否有能保证原子性的操作

阅读 5.2k
2 个回答

用upsert和inc解决了+unique index解决了,多谢
看下update的文档:

The remaining operations would either:

1 update the newly inserted document, or
fail when they attempted to insert a duplicate.
2 If the operation fails because of a duplicate index key error, applications may retry the operation which will succeed as an update operation.

我们可以看下update的解释,首先update最新的document,如果没有则进行插入,如果因为重复的主键更新失败,那么就重新再执行update的动作。

所以,我们应该实现加上唯一依赖

var userSchema = new mongoose.Schema({
    name: { type: String, index: { unique: true, dropDups: true }},
...}

而后使用update+inc+upsert即可

jsLib.update({name:value},{'$inc':{'num':1}},{upsert:true},function(err,data){
                console.log('save success...');
            });    

$inc操作符

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题