MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Aggiorna documenti in MongoDB

1. Panoramica

MongoDB è un database NoSQL multipiattaforma, orientato ai documenti e open source, scritto in C++. Inoltre, MongoDB offre prestazioni elevate, disponibilità elevata e ridimensionamento automatico.

Per aggiornare i documenti in MongoDB, possiamo utilizzare metodi diversi come updateOne , findOneAndUpdate, ecc. Inoltre, MongoDB fornisce vari operatori per i metodi di aggiornamento.

In questo tutorial verranno illustrati diversi approcci per eseguire operazioni di aggiornamento in MongoDB. Per ogni approccio, discuteremo prima la query della shell mongo e poi la sua implementazione in Java.

2. Configurazione del database

Prima di passare alle query di aggiornamento, creiamo innanzitutto un database, baeldung e una raccolta di campioni, studente:

use baeldung;
db.createCollection(student);

A titolo illustrativo, aggiungiamo alcuni documenti nella raccolta studente utilizzando insertMany domanda:

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
    }
]);

In caso di inserimento riuscito, otterremo un JSON con acknowledged:true :

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

Analizziamo ora i diversi modi per aggiornare i documenti in MongoDB.

3. Utilizzando updateOne Metodo

Un'operazione di aggiornamento in MongoDB può essere eseguita aggiungendo un nuovo campo, rimuovendo un campo o aggiornando un campo esistente. Il updateOne  il metodo aggiorna un singolo documento in una raccolta in base al filtro di query applicato. Prima trova il documento che corrisponde al filtro e poi aggiorna i campi specificati.

Inoltre, possiamo utilizzare diversi operatori come $set , $non impostato , $inc , ecc., con il metodo di aggiornamento.

Per dimostrare, esaminiamo la query per aggiornare un singolo documento di una raccolta:

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

Otterremo un output simile a quello mostrato di seguito:

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

Esaminiamo ora il codice del driver Java del precedente updateOne domanda:

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

Qui, per prima cosa abbiamo usato lo nome_studente campo per filtrare i documenti. Quindi aggiorniamo l'indirizzo del documento con nome_studente “Paolo Starc”.

4. Utilizzando updateMany Metodo

updateMany il metodo aggiorna tutti i documenti nelle raccolte MongoDB che corrispondono al filtro specificato. Uno dei vantaggi dell'utilizzo di updateMany è che possiamo aggiornare più documenti senza perdere i campi dei vecchi documenti.

Vediamo la query della shell MongoDB utilizzando updateMany metodo:

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

Il comando precedente restituirà il seguente output:

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

Qui, matchedCount contiene il numero di documenti corrispondenti, mentre modifiedCount contiene il numero dei documenti modificati.

Esaminiamo ora il codice del driver Java utilizzando updateMany metodo:

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

Qui, tutti i documenti con età meno di 20 verranno filtrati e la Recensione il campo verrà impostato su true .

5. Utilizzando replaceOne Metodo

Il replaceOne il metodo di MongoDB sostituisce l'intero documento. Uno degli svantaggi di replaceOne è che tutti i campi più vecchi verranno sostituiti dai nuovi campi e anche i campi più vecchi andranno persi:

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

In questo caso, otterremo il seguente output:

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

Se non vengono trovate corrispondenze, l'operazione restituisce il matchedCount come 0:

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

Scriviamo il codice del driver Java corrispondente usando replaceOne metodo:

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);

Nel codice precedente, abbiamo creato un documento con il quale verrà sostituito il documento precedente. Il documento con student_id 8764 verrà sostituito con il documento appena creato.

6. Utilizzando findOneAndReplace Metodo

Il findOneAndReplace method è uno dei metodi di aggiornamento avanzati forniti da MongoDB e sostituisce il primo documento abbinato in base ai criteri di selezione indicati. Per impostazione predefinita, questo metodo restituisce il documento originale. Possiamo utilizzare diverse opzioni di findOneAndReplace per ordinare e progettare i documenti, se necessario.

In breve, findOneAndReplace sostituisce il primo documento di corrispondenza della collezione sulla base del filtro applicato:

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

Questa query restituirà il seguente documento:

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

Se impostiamo returnNewDocumentvero , l'operazione restituirà invece il documento sostituito:

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

Usiamo ora findOneAndReplace metodo per proiettare lo student_id e età campi nel documento restituito:

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 
        } 
    }
);

L'output della query precedente conterrà solo i campi proiettati:

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

Il codice del driver Java della query precedente con varie opzioni di 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));

Nella query precedente, findOneAndReplace il metodo prima ordina i documenti in ordine crescente in base a roll_no, e il documento appena creato sostituisce il documento con student_id “8764”.

7. Utilizzando findOneAndUpdate Metodo

Il findOneAndUpdate il metodo aggiorna il primo documento corrispondente nella raccolta. Se più di un documento soddisfa i criteri di selezione, aggiorna solo il primo documento corrispondente. Quando aggiorniamo il documento, il valore di _id il campo rimane invariato:

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

L'output della query conterrà solo studentId e indirizzo del documento precedente:

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

Il codice del driver Java della query precedente, utilizzando diverse opzioni di findOneAndUpdate è il seguente:

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));

In questo caso, il findOneAndUpdate il metodo prima ordina il documento in ordine crescente in base a roll_no . La query precedente incrementa il roll_no  per 5 e poi restituisce student_id e indirizzo campi.