mongodb使用更新来避免竞争条件,当字段是空数组时更新错误

时间:2014-02-23 16:29:57

标签: node.js mongodb mongoose

这是我的收藏:

var schema = new mongoose.Schema({
        id: {type: Number, ref: 'id'},
        member_id: Number,
        title: String,
        content: String,
        pros: String,
        cons: String,
        createdAt: {type: Date, default: Date.now},
        vote: [{
            member_id:{type: Number,unique: true},
            support: Boolean,
            voted: Boolean, 
            createdAt: {type: Date, default: Date.now}
        }],
        comment: [{
            member_id: Number,
            support: Boolean,
            content:String,
            createdAt: {type: Date, default: Date.now}
        }]
    });

此数据库用于记录用户的投票。在服务器端,接收帖子以累积投票:

Topic.update({"id":id,"vote.member_id":member_id},  
        {$set:{ 'vote.$.member_id' : member_id, 'vote.$.support' : vote_to,'vote.$.voted' : true}} , { upsert: true }, function(err,test){
        if (err) {
            console.log(err);
            return res.json({error: true});
        }
        else{
            console.log(test);
            res.json({msg:"success vote"});
        }

但是在最初的情况下,换句话说,没有投票条目(投票是[]),它会收到一条错误消息: { [MongoError: Cannot apply the positional operator without a corresponding query field containing an array.] name: 'MongoError', err: 'Cannot apply the positional operator without a corresponding query field containing an array.', code: 16650, n: 0, connectionId: 133, ok: 1 }

如何解决此问题?

1 个答案:

答案 0 :(得分:0)

根据文档不建议在mongoDB中使用位置运算符($)和upsert ......

http://docs.mongodb.org/manual/reference/operator/update/positional/

  

不要将位置运算符$与upsert运算一起使用,因为   insert将在插入的文档中使用$作为字段名称。

因此,请删除更新命令中的upsert: true,看看它是否有效。 我建议您检查更新回调中的更新计数,如果它为零,那么您可以在投票数组中发送另一个$push的更新请求。