Перейти к основному содержимому

Обновление документов в MongoDB

· 6 мин. чтения

1. Обзор

MongoDB — это кроссплатформенная документоориентированная база данных NoSQL с открытым исходным кодом, написанная на C++. Кроме того, MongoDB обеспечивает высокую производительность, высокую доступность и автоматическое масштабирование.

Чтобы обновить документы в MongoDB, мы можем использовать различные методы, такие как updateOne , findOneAndUpdate и т. д . Кроме того, MongoDB предоставляет различные операторы для методов обновления.

В этом руководстве мы обсудим различные подходы к выполнению операций обновления в MongoDB. Для каждого подхода мы сначала обсудим запрос оболочки mongo, а затем его реализацию в Java.

2. Настройка базы данных

Прежде чем мы перейдем к запросам на обновление, давайте сначала создадим базу данных, foreach , и образец коллекции, student:

use foreach;
db.createCollection(student);

В качестве иллюстрации добавим несколько документов в коллекцию student с помощью запроса insertMany :

db.student.insertMany([
{
"student_id": 8764,
"student_name": "Paul Starc",
"address": "Hostel 1",
"age": 16,
"roll_no":199406
},
{
"student_id": 8765,
"student_name": "Andrew Boult",
"address": "Hostel 2",
"age": 18,
"roll_no":199408
}
]);

При успешной вставке мы получим JSON с accepted:true :

{
"acknowledged" : true,
"insertedIds" : [
ObjectId("621b078485e943405d04b557"),
ObjectId("621b078485e943405d04b558")
]
}

Давайте теперь углубимся в различные способы обновления документов в MongoDB.

3. Использование метода updateOne

Операцию обновления в MongoDB можно выполнить, добавив новое поле, удалив поле или обновив существующее поле. Метод updateOne обновляет один документ в коллекции на основе примененного фильтра запроса. Сначала он находит документ, соответствующий фильтру, а затем обновляет указанные поля.

Кроме того, мы можем использовать различные операторы, такие как $set , $unset , $inc и т. д ., с методом обновления.

Чтобы продемонстрировать, давайте рассмотрим запрос на обновление одного документа коллекции:

db.student.updateOne(
{
"student_name" : "Paul Starc"
},
{
$set: {
"address" : "Hostel 2"
}
}
);

Мы получим вывод, аналогичный показанному ниже:

{
"acknowledged":true,
"matchedCount":1,
"modifiedCount":1
}

Давайте теперь проверим код драйвера Java для приведенного выше запроса updateOne :

UpdateResult updateResult = collection.updateOne(Filters.eq("student_name", "Paul Starc"),
Updates.set("address", "Hostel 2"));

Здесь, во-первых, мы использовали поле student_name для фильтрации документов. Затем мы обновляем адрес документа с student_name «Paul Starc».

4. Использование метода updateMany

Метод updateMany обновляет все документы в коллекциях MongoDB, соответствующие заданному фильтру. Одним из преимуществ использования updateMany является то, что мы можем обновлять несколько документов без потери полей старых документов.

Давайте посмотрим на запрос оболочки MongoDB с использованием метода updateMany :

db.student.updateMany(
{
age: {
$lt: 20
}
},
{
$set:{
"Review" : true
}
}
);

Приведенная выше команда вернет следующий вывод:

{
"acknowledged":true,
"matchedCount":2,
"modifiedCount":2
}

Здесь matchedCount содержит количество совпадающих документов, тогда как ModifiedCount содержит количество измененных документов.

Давайте теперь посмотрим на код драйвера Java, используя метод updateMany :

UpdateResult updateResult = collection.updateMany(Filters.lt("age", 20), Updates.set("Review", true));

Здесь будут отфильтрованы все документы возрастом менее 20 лет, а в поле Review будет установлено значение true .

5. Использование метода replaceOne

Метод replaceOne MongoDB заменяет весь документ. Одним из недостатков replaceOne является то, что все старые поля будут заменены новыми полями, а также старые поля будут потеряны:

db.student.replaceOne(
{
"student_id": 8764
},
{
"student_id": 8764,
"student_name": "Paul Starc",
"address": "Hostel 2",
"age": 18,
"roll_no":199406
}
);

В этом случае мы получим следующий вывод:

{
"acknowledged":true,
"matchedCount":1,
"modifiedCount":1
}

Если совпадений не найдено, операция возвращает matchedCount как 0:

{
"acknowledged":true,
"matchedCount":0,
"modifiedCount":0
}

Напишем соответствующий код Java-драйвера с помощью метода replaceOne :

Document replaceDocument = new Document();
replaceDocument
.append("student_id", 8764)
.append("student_name", "Paul Starc")
.append("address", "Hostel 2")
.append("age",18)
.append("roll_no", 199406);
UpdateResult updateResult = collection.replaceOne(Filters.eq("student_id", 8764), replaceDocument);

В приведенном выше коде мы создали документ, которым будет заменен старый документ. Документ со student_id 8764 будет заменен вновь созданным документом.

6. Использование метода findOneAndReplace

Метод findOneAndReplace — это один из расширенных методов обновления, предоставляемых MongoDB, и он заменяет первый соответствующий документ на основе заданных критериев выбора. По умолчанию этот метод возвращает исходный документ. При необходимости мы можем использовать различные параметры findOneAndReplace для сортировки и проецирования документов.

Короче говоря, findOneAndReplace заменяет первый соответствующий документ коллекции на основе примененного фильтра:

db.student.findOneAndReplace(
{
"student_id" : {
$eq : 8764
}
},
{
"student_id" : 8764,
"student_name" : "Paul Starc",
"address": "Hostel 2",
"age": 18,
"roll_no":199406
},
{
returnNewDocument: false
}
);

Этот запрос вернет следующий документ:

{
"student_id":8764,
"student_name":"Paul Starc",
"address":"Hostel 1",
"age":16,
"roll_no":199406
}

Если мы установим для returnNewDocument значение true , операция вместо этого вернет замененный документ:

{
"student_id":8764,
"student_name":"Paul Starc",
"address":"Hostel 2",
"age":18,
"roll_no":199406
}

Давайте теперь воспользуемся методом findOneAndReplace для проецирования полей student_id и age в возвращаемом документе:

db.student.findOneAndReplace(
{
"student_id" : {
$eq : 8764
}
},
{
"student_id" : 8764,
"student_name" : "Paul Starc",
"address": "Hostel 2",
"age": 18,
"roll_no":199406
},
{
projection: {
"_id" : 0,
"student_id":1,
"age" : 1
}
}
);

Вывод вышеуказанного запроса будет содержать только проецируемые поля:

{
"student_id":"8764",
"age":16
}

Код драйвера Java приведенного выше запроса с различными параметрами findOneAndReplace:

Document replaceDocument = new Document();
replaceDocument
.append("student_id", 8764)
.append("student_name", "Paul Starc")
.append("address", "Hostel 2")
.append("age", 18)
.append("roll_no", 199406);
Document sort = new Document("roll_no", 1);
Document projection = new Document("_id", 0).append("student_id", 1).append("address", 1);
Document resultDocument = collection.findOneAndReplace(
Filters.eq("student_id", 8764),
replaceDocument,
new FindOneAndReplaceOptions().upsert(true).sort(sort).projection(projection).returnDocument(ReturnDocument.AFTER));

В приведенном выше запросе метод findOneAndReplace сначала отсортирует документы в порядке возрастания на основе roll_no, а вновь созданный документ заменит документ со student_id «8764».

7. Использование метода findOneAndUpdate

Метод findOneAndUpdate обновляет первый соответствующий документ в коллекции. Если критерию выбора соответствует несколько документов, обновляется только первый соответствующий документ. Когда мы обновляем документ, значение поля _id остается неизменным:

db.student.findOneAndUpdate(
{
"student_id" : 8764
},
{
$inc : {
"roll_no" : 5
}
},
{
sort: {
"roll_no" : 1
},
projection: {
"_id" : 0,
"student_id":1,
"address" : 1
}
}
);

Вывод запроса будет содержать только studentId и адрес более старого документа:

{
"student_id":8764,
"address":"Hostel 1"
}

Код драйвера Java приведенного выше запроса с использованием различных параметров findOneAndUpdate выглядит следующим образом :

Document sort = new Document("roll_no", 1);
Document projection = new Document("_id", 0).append("student_id", 1).append("address", 1);
Document resultDocument = collection.findOneAndUpdate(
Filters.eq("student_id", 8764),
Updates.inc("roll_no", 5),
new FindOneAndUpdateOptions().sort(sort).projection(projection).returnDocument(ReturnDocument.BEFORE));

В этом случае метод findOneAndUpdate сначала отсортирует документ в порядке возрастания на основе roll_no . Приведенный выше запрос увеличивает значение roll_no на 5, а затем возвращает поля student_id и address .

8. Заключение

В этой статье мы рассмотрели различные способы обновления документов в MongoDB. Сначала мы рассмотрели запрос оболочки MongoDB, а затем обсудили соответствующий код драйвера Java.

Реализацию всех этих примеров и фрагментов кода можно найти на GitHub .