1. Общ преглед
$push е оператор за актуализиране в MongoDB, който добавя стойността в масив. За разлика от това, $set Операторът се използва за актуализиране на стойността на съществуващо поле в документа.
В този кратък урок ще ви представим как да изпълните $push и $set операции заедно в една заявка за актуализиране.
2. Инициализация на база данни
Преди да продължим напред, за да извършим множество операции по актуализиране, първо трябва да настроим база данни baeldung и марки за колекция от проби :
use baeldung;
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 Shell Query
В 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 shell за използване на $push и $set оператор заедно. Тук ще се научим да прилагаме същото, използвайки кода на драйвера на Java.
Преди да продължим напред, нека първо се свържем с DB и необходимата колекция:
MongoClient mongoClient = new MongoClient(new MongoClientURI("localhost", 27017);
MongoDatabase database = mongoClient.getDatabase("baeldung");
MongoCollection<Document> collection = database.getCollection("marks");
Тук се свързваме с MongoDB, който работи на порт по подразбиране 27017 на порта на localhost.
Нека сега да разгледаме кода на драйвера на 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” .