E11000 повторяющаяся ошибка ключа в коллекции.updateOne [duplicate]

В Angular 5

вы можете просто сказать

this.http.get<Example>('assets/example.json')

Это даст вам Observable<Example>

4
задан cheks 18 May 2016 в 09:34
поделиться

2 ответа

Ускорение, которое приводит к вставке документа, не является полностью атомной операцией. Подумайте о том, что upsert выполняет следующие дискретные шаги:

  1. Запрос для подтвержденного документа для подтверждения.
  2. Если документ существует, выполните атомарное обновление существующего документа.
  3. Else (документ не существует), атомарно вставить новый документ, который включает в себя поля запроса и обновление.

Таким образом, шаги 2 и 3 являются атомарными, но другое 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.

Кроме того, вам не нужно вручную создавать индекс на _id, поскольку все коллекции MongoDB имеют уникальный индекс на _id независимо. Таким образом, вы можете удалить эту строку:

monitorSchema.index({_id: -1}); // Not needed
13
ответ дан JohnnyHK 18 August 2018 в 06:49
поделиться
  • 1
    Вы хотите сказать, мне нужен метод изменения .update, чтобы найти + update \ insert? – cheks 30 May 2016 в 07:09
  • 2
    @cheks Нет, я говорю, что это шаги, которые выполняет update upsert. Вот почему вы не можете избежать возможности попадания в дубликат ключевой ошибки, поэтому вам нужно проверить наличие ошибки и восстановить ее в своем коде. – JohnnyHK 30 May 2016 в 13:25
  • 3
    Я думаю, что раньше, но я не уверен, что это лучший способ. Благодаря! – cheks 30 May 2016 в 14:55

Автоматически уникальный индекс будет создан из поля _id.

Управляете ли вы _id с помощью custom value или mongodb, управляя ObjectId в поле _id.

Вы пытаетесь ввести запись с помощью _id: 24392490, которая уже существует. Таким образом, хотя вы использовали upsert, это не позволит, потому что _id - уникальный индекс.

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

Как и в вашей реализации для генерации _id, это позволит вставить только 1 запись за 1 - 1,5 минуты ( Точно одна минута, если круг не используется).

0
ответ дан Hiren S. 18 August 2018 в 06:49
поделиться
  • 1
    Я думаю, вы не знаете, как работает обновление с upsert ... теперь у меня есть более 5000 обновлений в минуту! но некоторое время я получаю двойную ключевую ошибку. – cheks 20 May 2016 в 06:50
Другие вопросы по тегам:

Похожие вопросы: