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

Come aggiornare un campo utilizzando il suo valore precedente in MongoDB/Mongoose

Non puoi fare riferimento ai valori del documento che desideri aggiornare, quindi avrai bisogno di una query per recuperare il documento e un'altra per aggiornarlo. Sembra che ci sia una richiesta di funzionalità per quello in OPEN stato dal 2016.

Se hai una collezione con documenti simili a:

{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name" : "bar" }

Usando la shell MongoDB, puoi fare qualcosa del genere:

db.test.find({ name: "bar" }).snapshot().forEach((doc) => {
    doc.name = "foo-" + doc.name;

    db.test.save(doc);
});

Il documento verrà aggiornato come previsto:

{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name": "foo-bar" }

Nota il .snapshot() call. Ciò garantisce che la query non restituirà un documento più volte perché un'operazione di scrittura intermedia lo sposta a causa dell'aumento delle dimensioni del documento.

Applicando questo al tuo esempio Mongoose, come spiegato in questo esempio ufficiale :

Cat.findById(1, (err, cat) => {
    if (err) return handleError(err);

    cat.name = cat.name + "bar";

    cat.save((err, updatedCat) => {
        if (err) return handleError(err);

        ...
    });
});

Vale la pena ricordare che esiste un $concat operatore nel framework di aggregazione, ma sfortunatamente non puoi usarlo in un update interrogazione.

Ad ogni modo, a seconda di cosa devi fare, puoi usarlo insieme a $out operatore per salvare i risultati dell'aggregazione in una nuova raccolta.

Con lo stesso esempio, farai:

db.test.aggregate([{
    $match: { name: "bar" }
}, {
    $project: { name: { $concat: ["foo", "-", "$name"] }}
}, {
    $out: "prefixedTest"
}]);

E una nuova raccolta prefixedTest verrà creato con documenti simili a:

{ "_id" : ObjectId("XXX"), "name": "foo-bar" }

Solo come riferimento, c'è un'altra domanda interessante su questo stesso argomento con alcune risposte che vale la pena leggere:Aggiorna campo MongoDB utilizzando il valore di un altro campo