Создание документов с помощью upsert
"Upsert" (обновление или вставка) — это особый тип операции обновления, который либо обновляет документ, если он существует, либо вставляет новый, если его нет. Это полезно для того, чтобы избежать раздельной логики "проверить, затем вставить" и обеспечивает атомарность операций с базой данных. Операции Upsert особенно ценны в сценариях, когда вы хотите:
- Обеспечить согласованность данных: Вместо того чтобы сначала проверять существование документа, а затем решать, вставлять или обновлять, вы можете выполнить одну атомарную операцию, которая обрабатывает оба случая.
- Обрабатывать параллельные операции: В многопользовательской среде upsert предотвращает состояние гонки (race conditions), когда другой процесс может вставить тот же документ между вашей операцией проверки и вставки.
- Упростить логику приложения: Уменьшает потребность в сложной условной логике в коде вашего приложения, делая его более поддерживаемым и менее подверженным ошибкам.
Вы можете включить это поведение, добавив опцию upsert: true к вашей команде обновления.
Попробуем добавить новую книгу, "Cloud Computing Essentials". Поскольку этой книги нет в нашей коллекции, операция upsert ее создаст.
db.books.updateOne(
{ title: "Cloud Computing Essentials" },
{ $set: { author: "David Lee", year: 2023, pages: 300 } },
{ upsert: true }
);
Команда состоит из трех частей:
- Фильтр:
{ title: "Cloud Computing Essentials" }
- Обновление:
{ $set: { ... } }
- Опции:
{ upsert: true }
Поскольку ни один документ не соответствовал фильтру, был создан новый. Объект результата отражает это, включая upsertedId.
{
acknowledged: true,
matchedCount: 0,
modifiedCount: 0,
upsertedCount: 1,
upsertedId: ObjectId("...")
}
Теперь давайте выполним ту же команду еще раз. На этот раз MongoDB найдет только что созданный документ и обновит его.
db.books.updateOne(
{ title: "Cloud Computing Essentials" },
{ $set: { author: "David Lee", year: 2023, pages: 300 } },
{ upsert: true }
);
Результат теперь показывает matchedCount: 1. Поскольку данные, которые мы устанавливаем, совпадают с существующими данными, modifiedCount равен 0. Если бы мы изменили значение, modifiedCount был бы равен 1.
{
"acknowledged": true,
"insertedId": null,
"matchedCount": 1,
"modifiedCount": 0,
"upsertedCount": 0
}
Вы можете убедиться, что новая книга существует в коллекции.
db.books.findOne({ title: "Cloud Computing Essentials" });
Вывод отобразит только что созданный документ.
{
_id: ObjectId("..."),
title: 'Cloud Computing Essentials',
author: 'David Lee',
year: 2023,
pages: 300
}
Когда вы закончите, вы можете выйти из оболочки MongoDB Shell.
exit;