복붙노트

[MONGODB] upsert와 키 오류를 중복 몽구스

MONGODB

upsert와 키 오류를 중복 몽구스

나는 중복 키에 문제가 있습니다. 답변을 찾지은`t 긴 시간입니다. 도움이 날이 문제를 해결하거나 내가 중복 키 오류가 발생하는 이유를 설명하십시오.

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 : 64, 66, 68, 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));
};

해결법

  1. ==============================

    1.문서 삽입에 그 결과 upsert는 완전히 원자 작동하지 않습니다. 다음 개별 단계를 수행하기로 upsert 생각 :

    문서 삽입에 그 결과 upsert는 완전히 원자 작동하지 않습니다. 다음 개별 단계를 수행하기로 upsert 생각 :

    그래서 2 단계와 3 각 원자하지만, 코드의 요구가 중복 키 오류를 확인하고 그가 발생하는 경우 upsert을 다시 시도 할 수 있도록 다른 upsert 1 단계 이후에 발생할 수 있습니다. 그 시점에서 당신은 항상 성공할 수 있도록 그 _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와 문서의 다른 삽입이 발생하지 않는 것이라고 어떤 경우에 이런 일이 왜 당신은 여전히 ​​궁금 할 것이다.

    모든 MongoDB의 컬렉션에 관계없이 _id에 고유 인덱스를 가지고 또한, 수동 _id에 인덱스를 만들 필요가 없습니다. 그래서 당신은이 줄을 제거 할 수 있습니다 :

    monitorSchema.index({_id: -1}); // Not needed
    
  2. from https://stackoverflow.com/questions/37295648/mongoose-duplicate-key-error-with-upsert by cc-by-sa and MIT license