1. Panoramica
$push è un operatore di aggiornamento in MongoDB che aggiunge il valore in un array. Al contrario, il $set viene utilizzato per aggiornare il valore di un campo esistente nel documento.
In questo breve tutorial presenteremo come eseguire $push e $set operazioni insieme in un'unica query di aggiornamento.
2. Inizializzazione database
Prima di procedere con le operazioni di aggiornamento multiple, è necessario configurare un database baeldung e segni da collezione di campioni :
use baeldung;
db.createCollection(marks);
Inseriamo alcuni documenti nella raccolta segni utilizzando insertMany metodo del 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
}
]
}
]);
In caso di inserimento riuscito, la query di cui sopra restituirà la seguente risposta:
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("622300cc85e943405d04b567"),
ObjectId("622300cc85e943405d04b568")
]
}
Finora, abbiamo inserito con successo alcuni documenti campione nella raccolta segni .
3. Comprendere il problema
Per capire il problema, comprendiamo prima il documento che abbiamo appena inserito. Include i dettagli degli studenti e i voti da loro ottenuti in diverse materie. I totalMarks è la somma dei voti ottenuti nelle diverse materie.
Consideriamo una situazione in cui desideriamo aggiungere un nuovo soggetto in subjectDetails Vettore. Per rendere coerenti anche i dati, dobbiamo aggiornare i totalMarks campo pure.
In MongoDB, per prima cosa, aggiungeremo il nuovo soggetto all'array usando $push operatore. Quindi imposteremo i totalMarks campo a un valore particolare utilizzando il $set operatore.
Entrambe queste operazioni possono essere eseguite individualmente usando il $push e $set operatore, rispettivamente. Ma possiamo scrivere la query MongoDB per eseguire entrambe le operazioni insieme.
4. Utilizzo della query della shell MongoDB
In MongoDB, possiamo aggiornare più campi di un documento utilizzando i diversi operatori di aggiornamento. Qui useremo entrambi $push e $set operatori insieme in un updateOne interrogazione.
Esaminiamo l'esempio contenente entrambi $push e $set operatori insieme:
db.marks.updateOne(
{
"studentId": 1023
},
{
$set: {
totalMarks: 170
},
$push: {
"subjectDetails":{
"subjectId": 126,
"subjectName": "Java Programming",
"marks": 70
}
}
}
);
Qui, nella query precedente, abbiamo aggiunto la query di filtro basata su studentId. Una volta ottenuto il documento filtrato, aggiorniamo i totalMarks utilizzando l'operatore $set. In aggiunta a ciò, inseriamo i nuovi dati del soggetto in subjectDetails array usando $push operatore.
Di conseguenza, la query precedente restituirà il seguente output:
{
"acknowledged":true,
"matchedCount":1,
"modifiedCount":1
}
Qui, il matchedCount contiene il conteggio dei documenti corrispondente al filtro, mentre modifiedCount contiene il numero di documenti modificati.
5. Codice driver Java
Finora abbiamo discusso della query della shell mongo per usare $push e $set operatore insieme. Qui impareremo a implementare lo stesso usando il codice del driver Java.
Prima di andare avanti, connettiamoci al DB e alla raccolta richiesta:
MongoClient mongoClient = new MongoClient(new MongoClientURI("localhost", 27017);
MongoDatabase database = mongoClient.getDatabase("baeldung");
MongoCollection<Document> collection = database.getCollection("marks");
Qui ci stiamo connettendo a MongoDB, che è in esecuzione sulla porta predefinita 27017 su localhost.
Esaminiamo ora il codice del driver 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)));
In questo frammento di codice, abbiamo utilizzato updateOne metodo, che aggiorna un solo documento in base al filtro applicato studentId 1023. Abbiamo quindi utilizzato Updates.combine per eseguire più operazioni in una singola chiamata. Il campo totalMarks verrà aggiornato a 170 e un nuovo documento subjectData verrà inviato al campo dell'array "subjectDetails" .