1. Обзор
$push
— это оператор обновления в MongoDB, который добавляет значение в массив. Напротив, оператор $set
используется для обновления значения существующего поля в документе.
В этом кратком руководстве мы расскажем, как выполнять операции $push
и $set
вместе в одном запросе на обновление.
2. Инициализация базы данных
Прежде чем мы перейдем к выполнению нескольких операций обновления , нам сначала нужно настроить foreach базы данных и
метки
коллекции образцов :
use foreach;
db.createCollection(marks);
Давайте вставим несколько документов в метки
коллекции, используя метод insertMany
MongoDB:
db.marks.insertMany([
{
"studentId": 1023,
"studentName":"James Broad",
"joiningYear":"2018",
"totalMarks":100,
"subjectDetails":[
{
"subjectId":123,
"subjectName":"Operating Systems Concepts",
"marks":40
},
{
"subjectId":124,
"subjectName":"Numerical Analysis",
"marks":60
}
]
},
{
"studentId": 1024,
"studentName":"Chris Overton",
"joiningYear":"2018",
"totalMarks":110,
"subjectDetails":[
{
"subjectId":123,
"subjectName":"Operating Systems Concepts",
"marks":50
},
{
"subjectId":124,
"subjectName":"Numerical Analysis",
"marks":60
}
]
}
]);
При успешной вставке приведенный выше запрос вернет следующий ответ:
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("622300cc85e943405d04b567"),
ObjectId("622300cc85e943405d04b568")
]
}
На данный момент мы успешно вставили несколько образцов документов в коллекционные метки
.
3. Понимание проблемы
Чтобы понять проблему, давайте сначала разберемся с документом, который мы только что вставили. Он включает в себя данные об учениках и оценки, полученные ими по разным предметам. TotalMarks — это
сумма оценок, полученных по разным предметам.
Давайте рассмотрим ситуацию, когда мы хотим добавить новую тему в массив subjectDetails .
Чтобы также сделать данные согласованными, нам также необходимо обновить поле totalMarks
.
В MongoDB сначала мы добавим новую тему в массив с помощью оператора $push .
Затем мы установим для поля totalMarks
определенное значение с помощью оператора $set .
Обе эти операции можно выполнять по отдельности с помощью операторов $push
и $set соответственно.
Но мы можем написать запрос MongoDB для одновременного выполнения обеих операций.
4. Использование запроса оболочки MongoDB
В MongoDB мы можем обновлять несколько полей документа, используя разные операторы обновления. Здесь мы будем использовать операторы $push
и $set
вместе в запросе updateOne
.
Давайте проверим пример, содержащий операторы $push
и $set вместе:
db.marks.updateOne(
{
"studentId": 1023
},
{
$set: {
totalMarks: 170
},
$push: {
"subjectDetails":{
"subjectId": 126,
"subjectName": "Java Programming",
"marks": 70
}
}
}
);
Здесь, в приведенном выше запросе, мы добавили фильтрующий запрос на основе studentId.
Как только мы получим отфильтрованный документ, мы обновим totalMarks
с помощью оператора $set. В дополнение к этому мы вставляем новые данные субъекта в массив subjectDetails
с помощью оператора $push .
В результате приведенный выше запрос вернет следующий вывод:
{
"acknowledged":true,
"matchedCount":1,
"modifiedCount":1
}
Здесь matchedCount
содержит количество документов, соответствующих фильтру, тогда как ModifiedCount содержит количество измененных
документов.
5. Код драйвера Java
До сих пор мы обсуждали запрос оболочки mongo для совместного использования операторов $push
и $set
. Здесь мы научимся реализовывать то же самое, используя код драйвера Java.
Прежде чем двигаться дальше, давайте сначала подключимся к БД и необходимой коллекции:
MongoClient mongoClient = new MongoClient(new MongoClientURI("localhost", 27017);
MongoDatabase database = mongoClient.getDatabase("foreach");
MongoCollection<Document> collection = database.getCollection("marks");
Здесь мы подключаемся к MongoDB, которая работает с портом по умолчанию 27017 на локальном хосте.
Давайте теперь посмотрим на код драйвера Java:
Document subjectData = new Document()
.append("subjectId", 126)
.append("subjectName", "Java Programming")
.append("marks", 70);
UpdateResult updateQueryResult = collection.updateOne(Filters.eq("studentId", 1023),
Updates.combine(Updates.set("totalMarks", 170),
Updates.push("subjectDetails", subjectData)));
В этом фрагменте кода мы использовали метод updateOne
, который обновляет только один документ на основе примененного фильтра studentId
1023. Затем мы использовали Updates.combine
для выполнения нескольких операций за один вызов. Поле totalMarks
будет обновлено до 170, а новый документ subjectData
будет помещен в поле массива «subjectDetails»
.
6. Заключение
В этой статье мы рассмотрели вариант использования одновременного применения нескольких операций в одном запросе MongoDB. Далее мы выполнили то же самое, используя запрос оболочки MongoDB и код драйвера Java.
Как всегда, исходный код и фрагменты кода всех примеров доступны на GitHub .