Как случайным образом выбрать две строки?

Ускорение, которое приводит к вставке документа, не является полностью атомной операцией. Подумайте о том, что 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

-1
задан piano0011 16 January 2019 в 07:40
поделиться

1 ответ

Вы можете сделать это легко с помощью запроса ниже. вам не нужно вкладывать в это столько логики.

select column_name from table_name order by RAND() limit 1
0
ответ дан Sayed Mohd Ali 16 January 2019 в 07:40
поделиться
Другие вопросы по тегам:

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