猫鼬重复键错误,并带有upsert

ks

我有重复密钥的问题。时间长了找不到答案。请帮助我解决此问题或解释为什么我得到重复的密钥错误。

Trace: { [MongoError: E11000 duplicate key error collection: project.monitor index: _id_ dup key: { : 24392490 }]
name: 'MongoError',
message: 'E11000 duplicate key error collection: project.monitor index: _id_ dup key: { : 24392490 }',
driver: true,
index: 0,
code: 11000,
errmsg: 'E11000 duplicate key error collection: project.monitor index: _id_ dup key: { : 24392490 }' }
at /home/project/app/lib/monitor.js:67:12
at callback (/home/project/app/node_modules/mongoose/lib/query.js:2029:9)
at Immediate.<anonymous> (/home/project/app/node_modules/kareem/index.js:160:11)
at Immediate._onImmediate (/home/project/app/node_modules/mquery/lib/utils.js:137:16)
at processImmediate [as _immediateCallback] (timers.js:368:17)

但是在监视器中,我使用upsert,所以为什么会出现重复错误?

monitor.js:62-70

监控架构

var monitorSchema = db.Schema({
   _id      : {type: Number, default: utils.minute},
   maxTicks : {type: Number, default: 0},
   ticks    : {type: Number, default: 0},
   memory   : {type: Number, default: 0},
   cpu      : {type: Number, default: 0},
   reboot   : {type: Number, default: 0},
streams  : db.Schema.Types.Mixed
}, {
collection: 'monitor',
strict: false
});

指数

monitorSchema.index({_id: -1});
Monitor = db.model('Monitor', monitorSchema);

并增加财产

exports.increase = function (property, incr) {
    var update = {};
    update[property] = utils.parseRound(incr) || 1;
    Monitor.update({_id: utils.minute()}, {$inc: update}, {upsert: true}, function (err) {
        if (err) {
            console.trace(err);
        }
    });
};

utils.js

exports.minute = function () {
    return Math.round(Date.now() / 60000);
};

exports.parseRound = function (num, round) {
    if (isNaN(num)) return 0;
    return Number(parseFloat(Number(num)).toFixed(round));
};
香港强尼

导致插入文档的ups不是完全原子的操作。将ups视为执行以下离散步骤:

  1. 查询标识的文档以进行增补。
  2. 如果文档存在,则以原子方式更新现有文档。
  3. 否则(该文档不存在),自动插入一个包含查询字段和更新的新文档。

因此,第2步和第3步都是原子操作,但是在第1步之后可能会发生另一个upsert,因此您的代码需要检查重复的键错误,然后再次尝试upsert(如果发生)。到那时,您知道_id存在的文档,因此它将始终成功。

例如:

var minute = utils.minute();
Monitor.update({ _id: minute }, { $inc: update }, { upsert: true }, function(err) {
    if (err) {
        if (err.code === 11000) {
            // Another upsert occurred during the upsert, try again. You could omit the
            // upsert option here if you don't ever delete docs while this is running.
            Monitor.update({ _id: minute }, { $inc: update }, { upsert: true },
                function(err) {
                    if (err) {
                        console.trace(err);
                    }
                });
        }
        else {
            console.trace(err);
        }
    }
});

有关相关文档,请参见此处

您可能仍然想知道,如果插入是原子的,为什么会发生这种情况,但这意味着在插入的文档被完全写入之前,不会对其进行任何更新,而不是不会_id出现具有相同文档的其他插入

另外,您无需手动创建索引,_id因为所有MongoDB集合都具有唯一的索引_id因此,您可以删除以下行:

monitorSchema.index({_id: -1}); // Not needed

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

猫鼬重复键错误,并带有upsert

来自分类Dev

猫鼬和mongoDB-重复键错误

来自分类Dev

如何使用带有动态键的猫鼬模型架构?

来自分类Dev

猫鼬-由:: 11000 E11000重复键错误索引引起?

来自分类Dev

带有ObjectID引用的RESTful猫鼬

来自分类Dev

猫鼬查询带有通配符的子句

来自分类Dev

带有多个实例的猫鼬$ in数组

来自分类Dev

错误:仅在服务器上找不到带有猫鼬的模块“ ./drivers”

来自分类Dev

猫鼬:E11000重复键会在出现错误的情况下更改返回消息的类型

来自分类Dev

外键猫鼬

来自分类Dev

使用猫鼬挂钩重试保存重复的密钥错误

来自分类Dev

不同数据类型的相同操作的重复代码,带有猫鼬的 Express(nodejs) 应用程序

来自分类Dev

我得到所有带有填充猫鼬的文档

来自分类Dev

带有猫的箭头键/读取

来自分类Dev

如何在猫鼬中编辑所有键

来自分类Dev

检索猫鼬文档中对象的所有键

来自分类Dev

使猫鼬更新数组的所有指定键

来自分类Dev

如何在猫鼬中编辑所有键

来自分类Dev

猫鼬解析错误

来自分类Dev

猫鼬保存错误

来自分类Dev

猫鼬分组错误

来自分类Dev

猫鼬4.1混合类型架构upsert

来自分类Dev

猫鼬:带$ sum的Upsert文档

来自分类Dev

猫鼬4.1混合类型架构upsert

来自分类Dev

猫鼬不返回带有findById的输出

来自分类常见问题

从猫鼬返回带有.populate()的某些字段

来自分类Dev

mongodb合并等效项(带有猫鼬)

来自分类Dev

猫鼬获取带有值的日期数组

来自分类Dev

在猫鼬中创建带有{strict:false}的文档